Neon read replicas are independent read-only compute instances that can significantly enhance database performance and scalability. By distributing read operations across these replicas, you can reduce latency and improve overall system responsiveness, especially for read-heavy applications. A standout feature of Neon is that adding a read replica doesn't require extra storage. This makes it a cost-effective way to scale your database, suitable for businesses of all sizes.
This guide explains how to integrate Neon read replicas into your Django application. You'll learn how to configure your Django database router to direct read operations to these replicas, optimizing your database performance and overall application speed.
Prerequisites
Before you begin, make sure you have:
- A Neon account and project. If you don't have one, sign up for a Neon account and create a project by following the Getting started guide.
- Basic knowledge of Django and Python.
- Python installed on your local machine.
Build the note-taking app
To demonstrate how to use Neon read replicas with Django, we'll build a simple note-taking application that uses a Neon database. We'll then update the application to use a read replica for read operations, improving the application's performance and scalability.
Part 1: Build the initial note-taking app with a single database
Set up the project
Create a new Django project and app:
This creates a new virtual environment, installs Django, and sets up a new Django project called django_notes
. We also create a new app called notes
, which will contain the logic for managing notes. For the database driver, we use psycopg2-binary
to connect to a PostgreSQL database.
Update settings
In django_notes/settings.py
, add the following:
The INSTALLED_APPS
array is updated to include the notes
app we just created. The DATABASES
dictionary is also updated to use a PostgreSQL database on Neon.
Create the Note model
In notes/models.py
, add:
The Note
model defines the structure for storing notes in the database. Each note will have a title
, content
, and a created_at
field, which is automatically populated with the current timestamp when a note is created.
Create views
In notes/views.py
, add:
Three views are defined here:
create_note
: Handles both displaying the note creation form (GET request) and saving the new note (POST request).list_notes
: Fetches and displays all the notes ordered by the creation time, showing the newest ones first.delete_note
: Handles the deletion of a specific note based on its ID.
Set up URLs
In django_notes/urls.py
:
We define the URL patterns for the project. The default route displays the list of notes, /create/
serves the note creation form, and /delete/<note_id>/
handles the deletion of a specific note.
Create templates
Create notes/templates/notes/base.html
:
This is the base HTML template, which provides the layout and structure for the pages. Other templates will extend this layout, using the block
tags to insert page-specific content.
Create notes/templates/notes/create_note.html
:
This template displays the form to create a new note. It extends the base template and includes a form with fields for the title and content. Upon submission, the form sends a POST
request to the server.
Create notes/templates/notes/list_notes.html
:
This template displays a list of all notes. Each note shows its title, content, and creation time. A delete button is also provided next to each note, allowing for easy deletion.
Run migrations and start the server
These commands generate and apply the database migrations for the Note model and start the development server, allowing you to access the app in your browser.
Visit http://localhost:8000
to test the note-taking app.
Part 2: Use a read replica for read-only operations
Create a read replica on Neon
To create a read replica:
- In the Neon Console, select Branches.
- Select the branch where your database resides.
- Click Add Read Replica.
- On the Add new compute dialog, select Read replica as the Compute type.
- Specify the Compute size settings options. You can configure a Fixed Size compute with a specific amount of vCPU and RAM (the default) or enable autoscaling by configuring a minimum and maximum compute size. You can also configure the Suspend compute after inactivity setting, which is the amount of idle time after which your read replica compute is automatically suspended. The default setting is 5 minutes.
note
The compute size configuration determines the processing power of your database. More vCPU and memory means more processing power but also higher compute costs. For information about compute costs, see Billing metrics.
- When you finish making selections, click Create.
Your read replica compute is provisioned and appears on the Computes tab of the Branches page.
Navigate to the Dashboard page, select the branch where the read replica compute was provisioned, and set the compute option to Replica to obtain the read replica connection string:
Set up database routing for read replicas
Create a new file notes/db_router.py
:
This PrimaryReplicaRouter
class defines the routing logic for database operations. The db_for_read method
routes all read operations to the 'replica' database, while db_for_write
directs write operations to the 'default' database. The allow_relation
and allow_migrate
methods are set to return True
, allowing all relations and migrations across databases.
Update django_notes/settings.py
:
In the settings.py
file, we define two database connections: 'default'
for the primary database and 'replica'
for the read replica. Both use the PostgreSQL engine and share the same database name, but have different host addresses. The DATABASE_ROUTERS
setting tells Django to use our custom PrimaryReplicaRouter
for database routing decisions.
With these configurations in place, Django will automatically route read queries to the read replica and write queries to the primary database, effectively distributing the database load and potentially improving your application's performance.
Conclusion
By leveraging Neon's read replicas in your Django application, you can significantly improve your application's performance and scalability. Django's database router makes it easy to set up and use read replicas without having to manually manage multiple database connections in your application code.
This setup allows you to distribute your read load across one or more read replicas while ensuring that all write operations are performed on the primary database. Monitor your application's performance and adjust the number of read replicas as needed to handle your specific load requirements.
You can find the source code for this application on GitHub:
Need help?
Join our Discord Server to ask questions or see what others are doing with Neon. Users on paid plans can open a support ticket from the console. For more details, see Getting Support.