The architecture of IMGZ
Posted on .
Every day at work, hundreds of customers ask us "can I get a large cappuccino?". Later, we go home and use the money to narrowly avoid starvation while working on IMGZ, the best image host, in true Silicon Valley spirit. We thought that some of the architectural challenges we faced while building the service would interest others, and decided to write about them to help our readers and change the world.
If you aren't familiar with IMGZ, it's an image host with a twist: You pay to host images, thus ensuring that we always have your best interests in mind and won't turn into a social network. In essence, we flip the traditional "startup giving away VC money to users" on its head, and take money from users. If that sounds good to you, you can sign up on our home page and we'll only be mildly surprised.
At IMGZ, we're passionate about two things: Serving images, and speaking about ourself in the plural so it doesn't look like it's the one-man sideproject it is, and we don't even really care about serving images that much. Today, though, we're going to talk about the former, and take a deep dive into the technical details of serving more than one million bytes of images per day while maintaining the elusive "nine fives" reliability guarantee we're loved for and usually uphold.
Our architecture is pretty simple, a fairly run-of-the-mill, scrappy-startup SaaS architecture which you've no doubt seen countless times before:
While designing the IMGZ storage and serving model, we wanted scalability and reliability to be our foremost concerns. After months of designs and grueling research, we ended up designing a Kafka-based georeplicated image processing pipeline over a multitenant, distributed, resilient microservices architecture, where metadata about each image is kept in a georeplicated MongoDB instance, and with images themselves stored in DynamoDB on AWS, ensuring scalability and low latency.
When we realized we didn't have investors to impress, we trashed that plan, as it sounded like too much work. We realize that architecture design nowadays is mostly aspirational, but at some point a startup needs to come to terms with the fact that it doesn't have ten million users right now, it probably won't have ten million users soon, and it'll likely never have ten users. Instead, we stored the images in a small Postgres database (yes, the actual image data itself), with a small Django app handling the business logic. Sexy.
When the user uploads an image, we process it, create thumbnails for displaying in various views of the website, and store it along with its metadata in the database, at least in theory. When a user requests the image, the request first goes through our CDN, which fetches the image from our server and then caches it forever, so each image is only served by us at most once. For our CDN (for serving, caching, georeplication, etc), we use CloudFlare's free tier, which is excellent. We ensure that we'll always remain in the free tier by providing a paid service nobody would actually ever pay for.
This is the heart of IMGZ:
Images, just like the one above, are the heart of our service, but let's not digress. The hardware is a $5/mo Hetzner VM that serves ~10 other projects, so it's pretty beefy. As our favorite proverb goes, "you don't need lots of resources when all your content is static and you can get someone else to serve it for free".
We're pretty confident in our ability to scale our infrastructure in the event that more users join the service, as our VPS provider has a button we can press to make the server larger, solving all scalability problems once and for all.
Moral of the story
This article was a bit boring, wasn't it? That's by design: Your architecture doesn't have to be exciting to work, especially in the early stages of a company. Doing the easiest thing that works (taking care not to paint yoursellf into a corner) is often the best way to start, since you usually don't even know where you'll end up.
To summarize, our architecture follows the tried-and-true Silicon Valley approach: Build the simplest thing you can, by piggybacking off of everyone's free tier, while they hope you one day become successful and pay them exorbitant amounts of money in return. The strategy to outsmarting them is simple:
Just make sure you never succeed.