This seems entirely reasonable.
Presumably your textures are stored as jpg or png images. These are variable compression formats used for the web, meaning the content of the image (and in the case of jpg, the quality of the compression) determines the size of the image. These are obviously convenient for web and even everyday usage as it can greatly reduce the storage size of the images compared to uncompressed equivalents.
Try opening up Photoshop and make a solid color 4096x4096 texture. Save that as a 32 bit tga file. That’ll be 64 megabytes. Now save it as a png file, it’ll be <60KB. jpg will be <110KB. This is an extreme example, but shows that there can be >1000x difference in size between compressed and uncompressed images, so 43x isn’t too bad.
However, GPUs can’t use images compressed in this format. There are several reasons for this, but the most basic issue is a GPU needs to be able to randomly access any texel on the image and get the color value quickly. Decompressing a jpg or png image can take quite a while, even on a modern computer, and especially relative to the time frames needed for a GPU (preferably microseconds or less). So GPUs instead use uncompressed, or fixed compression ratio image formats where the content of the image does not change the storage size, only resolution and format. This way if the GPU needs to access a specific texel, it can quickly calculate where in memory that data is and access it immediately.
By default when importing images into Unity at runtime, those images are converted to an uncompressed image and served to the GPU. This is because the step of re-compressing them to a GPU native compressed format isn’t free. In some cases it can take literally minutes for a single texture, for some formats and larger image sizes. Though the most recent versions of Unity have real-time compressors available for runtime importing that can take only a few milliseconds per image, though at the cost of a significantly reduced quality compared to in-editor compression.
They also default to using mipmaps which increase the space used by the texture by ~33%. So a 4096x4096 image will become around 85 megabytes.
As a side note, this is a big reason why web browsers eat up so much memory too. To display a compressed image you have to decompress it, and web browsers always use the uncompressed version of the image while displaying it.
So what’s the fix? There are a few options, though you should temper your expectations as for how much less memory you’ll be using as GPU compression formats, as generally they’re either 6:1 (w/o alpha) or 4:1 (w/ alpha) ratios, meaning you’re likely looking at reducing that 3.5 GB to just under 1 GB.
One is, as mentioned, runtime compression. This works, but do expect it to take a few extra milliseconds per image imported on a mobile device, and for the image quality to be significantly reduced. Search around on the forums and you’ll find examples on how to do that. It used to be you did it by creating a Texture2D of the appropriate image format you want (likely ETC2 if you need transparency), then importing an image into it. But I think there are slightly easier options today.
Another option would be to have multiple versions of the images on the server, small thumbnail versions and full size versions. Load all of the thumbnail versions to start with and if you need a full size version of the image only load it when needed, and unload it as soon as you don’t need it. This would let you keep the full quality version of the image and avoid the cost of compressing the image. But of course you’ll have to load the images each time they’re needed which also isn’t free. You could also have some cache of them and unload old ones once you’ve loaded too many.
The last option is don’t store them on the server as png images. Use asset bundles where they’ve been pre-compressed into GPU friendly formats. You can also use the ASTC format in that case, which has both better quality and better compression ratios vs the ETC2 format you’d be limited to when using runtime compression.