<p>Alright, so I'm working on an application which will use a Linux back-end running PostgreSQL to serve up images to a Windows box with the front end written in C#.NET, though the front-end should hardly matter.  My question is:</p>

<ul>
<li><strong>What is the best way to deal with storing images in Postgres?</strong></li>
</ul>

<p>The images are around 4-6 megapixels each, and we're storing upwards of 3000.  It might also be good to note: this is not a web application, there will at most be about two front-ends accessing the database at once.</p>

[{'answer_id': 54541, 'author': 'jcoby', 'author_id': 2884, 'author_profile': 'https://Stackoverflow.com/users/2884', 'pm_score': 5, 'selected': False, 'text': "<p>In the database, there are two options:</p>\n\n<ul>\n<li>bytea.  Stores the data in a column, exported as part of a backup.  Uses standard database functions to save and retrieve.  Recommended for your needs.</li>\n<li>blobs.  Stores the data externally, not normally exported as part of a backup.  Requires special database functions to save and retrieve.</li>\n</ul>\n\n<p>I've used bytea columns with great success in the past storing 10+gb of images with thousands of rows.  PG's TOAST functionality pretty much negates any advantage that blobs have.  You'll need to include metadata columns in either case for filename, content-type, dimensions, etc.</p>\n"}, {'answer_id': 54561, 'author': 'Kris Erickson', 'author_id': 3798, 'author_profile': 'https://Stackoverflow.com/users/3798', 'pm_score': 5, 'selected': False, 'text': "<p><strong>Update from 10 years later</strong>\nIn 2008 the hard drives you would run a database on would have much different characteristics and much higher cost than the disks you would store files on.  These days there are much better solutions for storing files that didn't exist 10 years ago and I would revoke this advice and advise readers to look at some of the other answers in this thread.</p>\n\n<p><strong>Original</strong></p>\n\n<p>Don't store in images in the database unless you absolutely have to.  I understand that this is not a web application, but if there isn't a shared file location that you can point to save the location of the file in the database.</p>\n\n<pre><code>//linuxserver/images/imagexxx.jpg\n</code></pre>\n\n<p>then perhaps you can quickly set up a webserver and store the web urls in the database (as well as the local path).  While databases can handle LOB's and 3000 images (4-6 Megapixels, assuming 500K an image) 1.5 Gigs isn't a lot of space file systems are much better designed for storing large files than a database is.</p>\n"}, {'answer_id': 100025, 'author': 'Ivan Krechetov', 'author_id': 6430, 'author_profile': 'https://Stackoverflow.com/users/6430', 'pm_score': 6, 'selected': False, 'text': '<p>Re jcoby\'s answer:</p>\n\n<p>bytea being a "normal" column also means the value being read completely into memory when you fetch it. Blobs, in contrast, you can stream into stdout. That helps in reducing the server memory footprint. Especially, when you store 4-6 MPix images.</p>\n\n<p>No problem with backing up blobs. pg_dump provides "-b" option to include the large objects into the backup.</p>\n\n<p>So, I prefer using pg_lo_*, you may guess.</p>\n\n<p>Re Kris Erickson\'s answer:</p>\n\n<p>I\'d say the opposite :). When images are not the only data you store, don\'t store them on the file system unless you absolutely have to. It\'s such a benefit to be always sure about your data consistency, and to have the data "in one piece" (the DB). BTW, PostgreSQL is great in preserving consistency.</p>\n\n<p>However, true, reality is often too performance-demanding ;-), and it pushes you to serve the binary files from the file system. But even then I tend to use the DB as the "master" storage for binaries, with all the other relations consistently linked, while providing some file system-based caching mechanism for performance optimization.  </p>\n'}, {'answer_id': 10267699, 'author': 'Peter Krauss', 'author_id': 287948, 'author_profile': 'https://Stackoverflow.com/users/287948', 'pm_score': 6, 'selected': False, 'text': '<p>Updating to 2012, when we see that image sizes, and number of images, are growing and growing, in all applications...</p>\n<p>We need some distinction between &quot;original image&quot; and &quot;processed image&quot;, like thumbnail.</p>\n<p>As Jcoby\'s answer says, there are two options, then, I recommend:</p>\n<ul>\n<li><p>use <em>blob</em> (Binary Large OBject): for original image store, at your table.   See Ivan\'s answer (no problem with backing up blobs!), <a href="https://www.postgresql.org/docs/current/lo.html" rel="noreferrer">PostgreSQL additional supplied modules</a>, <a href="https://stackoverflow.com/questions/4386030/">How-tos</a> etc.</p>\n</li>\n<li><p>use a separate database with <a href="https://www.postgresql.org/docs/current/dblink.html" rel="noreferrer">DBlink</a>: for original image store, at another (unified/specialized) database. In this case, I prefer <em>bytea</em>, but <em>blob</em>  is near the same. Separating database is the best way for a &quot;unified image webservice&quot;.</p>\n</li>\n<li><p>use <em>bytea</em> (BYTE Array): for caching thumbnail images. Cache the little images to send it fast to the web-browser (to avoiding rendering problems) and reduce server processing. Cache also essential metadata, like width and height. Database caching is the easiest way, but check your needs and server configs (ex. Apache modules): <a href="https://stackoverflow.com/questions/3748/storing-images-in-db-yea-or-nay">store thumbnails at file system</a> may be better, compare performances. Remember that it is a (unified) web-service, then can be stored at a separate database (with no backups), serving many tables.   See also <a href="https://www.postgresql.org/docs/current/datatype-binary.html" rel="noreferrer">PostgreSQL binary data types manual</a>, <a href="https://dba.stackexchange.com/questions/1742/how-to-insert-file-data-into-a-postgresql-bytea-column">tests with bytea column</a>, etc.</p>\n</li>\n</ul>\n<p>NOTE1: today the use of <a href="https://stackoverflow.com/questions/3748/storing-images-in-db-yea-or-nay">&quot;dual solutions&quot; (database+filesystem)</a> is deprecated (!). There are many advantages to using &quot;only database&quot; instead dual.  PostgreSQL have comparable performance and good tools for export/import/input/output.</p>\n<p>NOTE2: remember that PostgreSQL have only <em>bytea</em>, not have a default Oracle\'s <em>BLOB</em>: &quot;The SQL standard defines (...) BLOB. The input format is different from bytea, but the provided functions and operators are mostly the same&quot;,<a href="https://www.postgresql.org/docs/current/datatype-binary.html" rel="noreferrer">Manual</a>.</p>\n<hr />\n<p>EDIT <strong>2014</strong>: I have not changed the original text above today (my answer was Apr 22 \'12, now with 14 votes), <em>I\xa0am opening the answer for your changes</em>  (see &quot;Wiki mode&quot;, you can edit!), for <a href="https://en.wikipedia.org/wiki/Proofreading" rel="noreferrer">proofreading</a> and <strong>for updates</strong>. <br/>The question is stable (@Ivans\'s \'08 answer with 19 votes), please, help to improve this text.</p>\n'}, {'answer_id': 30565973, 'author': 'Kenyakorn Ketsombut', 'author_id': 1998944, 'author_profile': 'https://Stackoverflow.com/users/1998944', 'pm_score': 5, 'selected': False, 'text': '<p><strong>Quick update to mid 2015:</strong></p>\n\n<p>You can use the <strong>Postgres Foreign Data interface</strong>, to store the files in more suitable database. For example put the files in a GridFS which is part of MongoDB. Then use\n<a href="https://github.com/EnterpriseDB/mongo_fdw" rel="noreferrer">https://github.com/EnterpriseDB/mongo_fdw</a>\nto access it in Postgres.</p>\n\n<p>That has the advantages, that you can access/read/write/backup it in Postrgres and MongoDB, depending on what gives you more flexiblity.</p>\n\n<p><strong>There are also foreign data wrappers for file systems:</strong>\n<a href="https://wiki.postgresql.org/wiki/Foreign_data_wrappers#File_Wrappers" rel="noreferrer">https://wiki.postgresql.org/wiki/Foreign_data_wrappers#File_Wrappers</a></p>\n\n<p>As an example you can use this one:\n<a href="https://multicorn.readthedocs.org/en/latest/foreign-data-wrappers/fsfdw.html" rel="noreferrer">https://multicorn.readthedocs.org/en/latest/foreign-data-wrappers/fsfdw.html</a>\n(see here for brief usage example)</p>\n\n<p>That gives you the advantage of the consistency (all linked files are definitely there) and all the other ACIDs, while there are still on the actual file system, which means you can use any file system you want and the webserver can serve them directly (OS caching applies too).</p>\n'}, {'answer_id': 58229428, 'author': 'ccleve', 'author_id': 237815, 'author_profile': 'https://Stackoverflow.com/users/237815', 'pm_score': 3, 'selected': False, 'text': '<p>If your images are small, consider storing them as base64 in a plain text field. </p>\n\n<p>The reason is that while base64 has an overhead of 33%, with compression that mostly goes away. (See <a href="https://lemire.me/blog/2019/01/30/what-is-the-space-overhead-of-base64-encoding/" rel="noreferrer">What is the space overhead of Base64 encoding?</a>) Your database will be bigger, but the packets your webserver sends to the client won\'t be. In html, you can inline base64 in an &lt;img src=""> tag, which can possibly simplify your app because you won\'t have to serve up the images as binary in a separate browser fetch. Handling images as text also simplifies things when you have to send/receive json, which doesn\'t handle binary very well.</p>\n\n<p>Yes, I understand you could store the binary in the database and convert it to/from text on the way in and out of the database, but sometimes ORMs make that a hassle. It can be simpler just to treat it as straight text just like all your other fields. </p>\n\n<p>This is definitely the right way to handle thumbnails.</p>\n\n<p>(OP\'s images are not small, so this is not really an answer to his question.)</p>\n'}, {'answer_id': 72708366, 'author': 'Janac Meena', 'author_id': 1502439, 'author_profile': 'https://Stackoverflow.com/users/1502439', 'pm_score': 3, 'selected': False, 'text': "<p>2022 Answer</p>\n<p>The most common pattern now is to only store a reference to the image in your database, and store the image itself in a filesystem (i.e. S3 bucket).</p>\n<p>The benefit is that your database backups are smaller, there's no longer a single point of failure, load can now be distributed away from the database, and cloud storage buckets are often cheaper than database storage.</p>\n<p>The negative is that you have to manage images in two locations - delete one image and your app needs to keep track and delete it from the other.</p>\n"}]
['https://Stackoverflow.com/questions/54500', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/145/']