Apologies if this has already been discussed and solved. I recently needed to add A LOT of random textures to A LOT of instances. Using Octane Gradient Texture Nodes was a bit painful so I wrote a really simple OSL node to allow texture sheets. Using this method, we can pack lots of textures into a single grid. The projection node then samples one of the cells based on a the Random Color Node which is different for each instance. As long as your textures aren't to big, or you don't mind your texture sheet getting big, you can apply a lot of textures this way.
My notes from the OSL are here:
// A quick and dirty texture sheet projection node by James Dean.
// Set max count to the total number of images in your sheet (this can less than rows X columns; leave any unused cells on the right of the bottom row)
// Set rows and columns to... the number of rows and columns (what else would you set it to?).
// Connect a RandomColor Texture node up to the Random Texture slot.
// Connect the projection pin from the OSL node into the Texture Image node that holds the texture sheet
// Texture sheets don't have to be square, and nor do the cells (although they all have to be the same size).
// I suggest making the sheet pixel dimensions divisible by the number of rows and columns.
// Sticking to powers of 2 will probably make a programmer happy somewhere.