thumbnail
Mohamed Amine Terbah

Evolving Our Infrastructure: Why We Moved from Heroku Postgres to Neon

June 19, 2025

We recently completed a major backend migration: moving our primary production database from Heroku Postgres to Neon.

This move wasn’t about chasing shiny new tech or jumping at the next big thing. It was about unblocking ourselves for a better developer experience, smoother scaling, and more manageable costs. Postgres remains the backbone of DEV and Forem, but Neon gives us a more flexible and modern runtime for it and a foundation to build on going forward.

Now that we’re on the other side of the migration, we wanted to reflect on the move. We’re now benefiting from lower costs, tighter feedback loops, and more room to grow.

Why We Moved

First off, Heroku Postgres served us well. It helped us get up and running quickly and served as a reliable core from our humble beginnings more than eight years ago to an app that now serves millions of developers each month. But, over time, we ran into a few persistent friction points:

  • It was hard to run production-like environments without heavy lifting.
  • Read replica usage was limited and sometimes finicky.
  • Rigid resource allocation of traditional databases made scaling inefficient.
  • We had little control over how resources were allocated or billed.
  • We anticipate continuing to grow and use multiple databases, and the autoscaling functionality is a game changer.

Postgres has historically been our biggest single resource expense—far exceeding our compute and other infrastructure costs. It’s also super critical, and not an area where we would seek to reduce costs without also finding a way to make upgrades and improvements. The core database is just too important to consider cheaping out on.

So, in considering a search, we prioritized not just cost efficiency, but also tooling that helps us work with and secure our data as much as possible.

We researched a bunch of options and talked to multiple potential partners before landing on Neon as the best choice. We reached out to the team and were delighted to build a relationship, culminating in a 💎️ Diamond Sponsorship here on DEV and enhanced deals for our DEV++ members.


Better Developer Loops

One of the biggest wins has been the developer experience.

Neon’s branching system lets us spin up isolated database environments instantly. That means:

  • We can work with real data without worrying about collisions.
  • We can test migrations, schema changes, or edge cases in true-to-prod environments.
  • We can ensure feature previews that touch the database are actually feasible without a staging bottleneck.

We’ve also made more use of read replicas, something that we used to have to tread lightly around. Neon has made this so much simpler. Whether for offloading long-running queries, powering automation tooling, or experimenting with feature-specific read paths, spinning up a replica is no longer expensive or complex.

This has opened up new options for handling load and gives us a more future-proof path for experimentation.


Smarter Scaling, Lower Costs

Neon’s architecture separates storage and compute. We don’t have to scale everything together, which was always a painful limitation of the Heroku Postgres fixed-size offerings. Now we can tune our storage and compute needs independently, paying only for what we actually use.

The impact on cost has been meaningful. We’ve dropped a good chunk of our database bill by switching to Neon.


Flexibility for What’s Next

We appreciate the simplicity and accessibility we anticipate in unlocking PostgreSQL extensions and modern tooling that we aren’t yet using. This isn't just about what we need today; it's about how easily we can integrate new, powerful features tomorrow. The native support for pgvector, for instance, puts AI-powered features like semantic search and recommendations right at our fingertips. We're also keen to explore pg_search for more advanced full-text search capabilities directly within the database, simplifying our stack. Beyond search, the ecosystem tooling around APIs and authentication is a huge draw. The ability to leverage tools like the Neon Data API to quickly create and expose data endpoints, combined with robust authentication extensions, means we can build and secure new services faster than ever. For us, choosing Neon was about future-proofing our platform and making innovation much more attainable.


The Migration

Moving our database from Heroku to Neon was a major undertaking, and our top priority throughout the process was ensuring zero data loss and minimal downtime. To achieve this goal, we used a tool called Bucardo for the migration, which allowed us to move our data with virtually no downtime.

Bucardo is an asynchronous replication system for PostgreSQL. It works by creating triggers on your primary database that watch for changes. These changes are then collected and replayed on the target database, keeping it in sync with the source. To manage this process, we spun up Bucardo on a standalone DigitalOcean droplet in close coordination with the Neon team. This allowed it to connect to both our Heroku database and our new Neon database and facilitate the replication without impacting the performance of our primary application.

While Bucardo proved to be the right choice for a seamless transition, it wasn't without its quirks. The process was a bit finicky at times. The happy path always worked, but we had to restart the process at one point due to leftover triggers that caused issues.

Our intense focus on data integrity also meant we didn't fully anticipate the configuration adjustments that would be needed afterward.

We had been on Heroku for so long that its database configuration had become second nature to us—along with some defaults we had taken for granted. We just expected our database to behave in that specific way in all settings. This meant that after the migration to Neon, we had to fine-tune our setup, particularly around connection pooling and timeouts, to get everything working optimally. It took a few days of adjustments to get the performance to 100%, but we got there.

Overall, the move to Neon has been a huge success. We accomplished our primary goal of migrating without any downtime or data loss. Now, we're on a platform with new features that we're excited to use. We feel like we still get the developer experience we appreciate (being a Heroku-hosted app)—along with a much more flexible and powerful underlying infrastructure.


What's Next

We're already starting to integrate more of Neon’s features into our workflows:

  • Branches as a service for feature previews
  • Replica-backed experimentation without production impact
  • Cleaner separation between developer environments and production data

And while you don’t need Neon to run Forem—Postgres is still the default—we think this setup represents the kind of modern foundation that serious apps will increasingly rely on.


Final Thought

We’re always looking for tools that give us leverage without locking us in. Neon gave us a better Postgres, with fewer tradeoffs and more room to move.

We’re glad we made the jump.