How to store images in the database?

I am using Heroku to deploy my project and mlab for mongodb database. Now I want to store the profile pictures somewhere. Storing them in mlab is not a good option. The only option I can think of now is using a CDN? How are you storing images?

You could store an image in your database as a blob, but that's generally not a good idea as most databases aren't optimized for storing binaries such as images.

Considering Heroku has an ephemeral file system (i.e. you cannot persist uploaded files on the disk) your best approach is to upload the files to some online storage such as Amazon S3. (I think that's what you meant with CDN, but it's not exactly the same thing.)

The way it would work is the user uploads the file to your server (Heroku), and then your app uploads the file to your S3 bucket. Whenever you want to show the image you use the S3 URL.

Alternatively you could configure your S3 bucket such that the user can upload directly to S3 without the file ever touching your server. This generally provides a better user experience, but technically is a lot harder to achieve in a secure fashion. So my advice is not to bother with that until upload performance becomes a real issue.

Finally, the last option would be to use a SaaS that provides you with an upload widget, and takes care of uploading/processing/hosting files for you. Cloudinary has this feature.. This might be the easiest option, but probably the least flexible and most expensive.

Thanks Marc for the detailed answer. I would go with Amazon S3 option for now. BTW, How are you dealing with the images for WIP?

Uploads go to Heroku server which are then uploaded to S3 in a background job. We use imgix as a CDN in front of S3, so images are loaded faster and we can perform resizing/etc on-the-fly without having to generate them in advance. (Not as cost effective, but makes development a lot quicker.)

How does Cloudinary compare to Imgix?

I haven’t used Cloudinary so I’m not sure. I believe they offer some extra features like the upload widget. I haven’t needed any of that though so I’m happy with imgix.

Cloudinary has direct upload from browser which make easy to implement