Getting Started on Heroku with Python
Introduction
Complete this tutorial to deploy a sample Python Django app to Cedar, the legacy generation of the Heroku platform. To deploy the app to the Fir generation, only available to Heroku Private Spaces, follow this guide instead.
The tutorial assumes that you have:
- A verified Heroku Account
- An Eco dynos plan subscription (recommended)
- Python version 3.10 or newer (ideally 3.14) installed locally - see the installation guides for macOS, Windows, and Linux.
Using dynos and databases to complete this tutorial counts towards your usage. We recommend using our low-cost plans to complete this tutorial. Eligible students can apply for platform credits through our new Heroku for GitHub Students program.
Set Up
Install the Heroku Command Line Interface (CLI). Use the CLI to manage and scale your app, provision add-ons, view your logs, and run your app locally.
The Heroku CLI requires Git, the popular version control system. If you donโt already have Git installed, complete the following before proceeding:
Download and run the installer for your platform:
Download the appropriate installer for your Windows installation:
You can find more installation options for the Heroku CLI here.
After installation, you can use the heroku command from your command shell.
To log in to the Heroku CLI, use the heroku login command:
$ heroku login
heroku: Press any key to open up the browser to login or q to exit:
Opening browser to https://cli-auth.heroku.com/auth/cli/browser/***
heroku: Waiting for login...
Logging in... done
Logged in as me@example.com
This command opens your web browser to the Heroku login page. If your browser is already logged in to Heroku, click the Log In button on the page.
This authentication is required for the heroku and git commands to work correctly.
If you have any problems installing or using the Heroku CLI, see the main Heroku CLI article for advice and troubleshooting steps.
If youโre behind a firewall that uses a proxy to connect with external HTTP/HTTPS services, set the HTTP_PROXY or HTTPS_PROXY environment variables in your local development environment before running the heroku command.
Clone the Sample App
If youโre new to Heroku, itโs recommended that you complete this tutorial using the Heroku-provided sample application.
To deploy an existing application, follow the Preparing a Codebase for Heroku Deployment article instead.
Clone the sample application to get a local version of the code. Execute these commands in your local command shell or terminal:
$ git clone https://github.com/heroku/python-getting-started.git
$ cd python-getting-started
You now have a functioning Git repository that contains a simple Python app, that uses the web framework Django. It includes a .python-version file specifying the Python version to use and a requirements.txt, used by Pythonโs dependency manager, pip.
Create Your App
Using a dyno and a database to complete this tutorial counts towards your usage. Delete your app, and database as soon as youโre done to control costs.
Apps use Eco dynos if youโre subscribed to Eco by default. Otherwise, it defaults to Basic dynos. The Eco dynos plan is shared across all Eco dynos in your account. Itโs recommended if you plan on deploying many small apps to Heroku. Learn more here. Eligible students can apply for platform credits through our Heroku for GitHub Students program.
Create an app on Heroku to prepare the platform to receive your source code:
$ heroku create
Creating app... done, dry-stream-67925
https://dry-stream-67925-bd29310e83fc.herokuapp.com/ | https://git.heroku.com/dry-stream-67925.git
When you create an app, a Git remote named heroku is also created and added to your local repository configuration. Git remotes are versions of your repository that live on other servers. You can deploy your app by pushing code to that special Heroku-hosted remote associated with your app.
Heroku generates a random name for your app, in this case, dry-stream-67925. You can specify your own app name.
Deploy the App
Using a dyno to complete this tutorial counts towards your usage. Delete your app and database as soon as youโre done to control costs.
Deploy your code. This command pushes the main branch of the sample repo to your heroku remote, which then deploys to Heroku:
$ git push heroku main
remote: Updated 31 paths from f2d57e0
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Building on the Heroku-24 stack
remote: -----> Determining which buildpack to use for this app
remote: -----> Python app detected
remote: -----> Using Python 3.14 specified in .python-version
remote: -----> Installing Python 3.14.4
remote: -----> Installing pip 26.0.1
remote: -----> Installing dependencies using 'pip install -r requirements.txt'
remote: Collecting django<6.1,>=6.0 (from -r requirements.txt (line 1))
remote: Downloading django-6.0.5-py3-none-any.whl.metadata (3.9 kB)
remote: Collecting gunicorn<26,>=25 (from -r requirements.txt (line 2))
remote: Downloading gunicorn-25.3.0-py3-none-any.whl.metadata (5.5 kB)
remote: Collecting dj-database-url<4,>=3 (from -r requirements.txt (line 3))
remote: Downloading dj_database_url-3.1.2-py3-none-any.whl.metadata (13 kB)
remote: Collecting whitenoise<7,>=6 (from -r requirements.txt (line 4))
remote: Downloading whitenoise-6.12.0-py3-none-any.whl.metadata (3.7 kB)
remote: Collecting asgiref>=3.9.1 (from django<6.1,>=6.0->-r requirements.txt (line 1))
remote: Downloading asgiref-3.11.1-py3-none-any.whl.metadata (9.3 kB)
remote: Collecting sqlparse>=0.5.0 (from django<6.1,>=6.0->-r requirements.txt (line 1))
remote: Downloading sqlparse-0.5.5-py3-none-any.whl.metadata (4.7 kB)
remote: Collecting packaging (from gunicorn<26,>=25->-r requirements.txt (line 2))
remote: Downloading packaging-26.2-py3-none-any.whl.metadata (3.5 kB)
remote: Downloading django-6.0.5-py3-none-any.whl (8.4 MB)
remote: Downloading gunicorn-25.3.0-py3-none-any.whl (208 kB)
remote: Downloading dj_database_url-3.1.2-py3-none-any.whl (9.0 kB)
remote: Downloading whitenoise-6.12.0-py3-none-any.whl (20 kB)
remote: Downloading asgiref-3.11.1-py3-none-any.whl (24 kB)
remote: Downloading sqlparse-0.5.5-py3-none-any.whl (46 kB)
remote: Downloading packaging-26.2-py3-none-any.whl (100 kB)
remote: Installing collected packages: whitenoise, sqlparse, packaging, asgiref, gunicorn, django, dj-database-url
remote: Successfully installed asgiref-3.11.1 dj-database-url-3.1.2 django-6.0.5 gunicorn-25.3.0 packaging-26.2 sqlparse-0.5.5 whitenoise-6.12.0
remote: -----> $ python manage.py collectstatic --noinput
remote: WARNING:root:No DATABASE_URL environment variable set, and so no databases setup
remote:
remote: 1 static file copied to '/tmp/build_9cffb351/staticfiles', 1 post-processed.
remote:
remote: -----> Saving cache
remote:
remote: ! Note: We recently added support for the package manager uv:
remote: ! https://devcenter.heroku.com/changelog-items/3238
remote: !
remote: ! It's now our recommended Python package manager, since it
remote: ! supports lockfiles, is faster, gives more helpful error
remote: ! messages, and is actively maintained by a full-time team.
remote: !
remote: ! If you haven't tried it yet, we suggest you take a look!
remote: ! https://docs.astral.sh/uv/
remote:
remote: -----> Discovering process types
remote: Procfile declares types -> web
remote:
remote: -----> Compressing...
remote: Done: 26.1M
remote: -----> Launching...
remote: Released v3
remote: https://dry-stream-67925-bd29310e83fc.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/dry-stream-67925.git
* [new branch] main -> main
Visit the app at the URL shown in the logs. As a shortcut, you can also open the website as follows:
$ heroku open
Understanding the Procfile
Use a Procfile, a text file in the root directory of your application, to explicitly declare what command to execute to start your app.
The Procfile in the example app looks like this:
web: gunicorn --config gunicorn.conf.py gettingstarted.wsgi
This Procfile declares a process type web and the command needed to run it. The name web is important here because it declares that this process type attaches to Herokuโs HTTP routing stack and receives web traffic when deployed. The command used here runs Gunicorn, the web server, and passes in a configuration file.
A Procfile can contain additional process types. For example, you can declare a background worker process that processes items off a queue.
Microsoft Windows
The sample app has an additional Procfile for local development on Microsoft Windows, located in the file Procfile.windows. Later tutorial steps use this instead to start a different web server compatible with Windows.
web: python manage.py runserver %PORT%
View Logs
Heroku treats logs as streams of time-ordered events, aggregated from the output streams of all your app and Heroku components. Heroku provides a single stream for all events.
View information about your running app by using one of the logging commands, heroku logs --tail:
$ heroku logs --tail
2026-05-05T22:03:25.045822+00:00 heroku[web.1]: Starting process with command `gunicorn --config gunicorn.conf.py gettingstarted.wsgi`
2026-05-05T22:03:25.834180+00:00 app[web.1]: Python buildpack: Detected 512 MB available memory and 8 CPU cores.
2026-05-05T22:03:25.834264+00:00 app[web.1]: Python buildpack: Defaulting WEB_CONCURRENCY to 2 based on the available memory.
2026-05-05T22:03:26.075725+00:00 app[web.1]: WARNING:root:No DATABASE_URL environment variable set, and so no databases setup
2026-05-05T22:03:26.092306+00:00 app[web.1]: [2026-05-05 22:03:26 +0000] [2] [INFO] Starting gunicorn 25.3.0
2026-05-05T22:03:26.092437+00:00 app[web.1]: [2026-05-05 22:03:26 +0000] [2] [INFO] Listening at: (2)
2026-05-05T22:03:26.092465+00:00 app[web.1]: [2026-05-05 22:03:26 +0000] [2] [INFO] Using worker: gthread
2026-05-05T22:03:26.094758+00:00 app[web.1]: [2026-05-05 22:03:26 +0000] [8] [INFO] Booting worker with pid: 8
2026-05-05T22:03:26.105504+00:00 app[web.1]: [2026-05-05 22:03:26 +0000] [9] [INFO] Booting worker with pid: 9
2026-05-05T22:03:26.157686+00:00 app[web.1]: [2026-05-05 22:03:26 +0000] [2] [INFO] Control socket listening at /app/.gunicorn/gunicorn.ctl
2026-05-05T22:03:26.212738+00:00 heroku[web.1]: State changed from starting to up
2026-05-05T22:03:31.746535+00:00 app[web.1]: gunicorn method=GET path="/" status=200 duration=8ms request_id=3ac83044-61d8-4355-2df7-967bd298b679 fwd="123.456.789.0" user_agent="curl/8.7.1"
2026-05-05T22:03:31.746587+00:00 heroku[router]: at=info method=GET path="/" host=dry-stream-67925-bd29310e83fc.herokuapp.com request_id=3ac83044-61d8-4355-2df7-967bd298b679 fwd="123.456.789.0" dyno=web.1 connect=0ms service=10ms status=200 bytes=9585 protocol=http1.1 tls=false
To generate more log messages, refresh the app in your browser.
To stop streaming the logs, press Control+C.
Scale the App
After deploying the sample app, it automatically runs on a single web dyno. Think of a dyno as a lightweight container that runs the command specified in the Procfile.
You can check how many dynos are running by using the ps command:
$ heroku ps
=== web (Basic): gunicorn --config gunicorn.conf.py gettingstarted.wsgi (1)
web.1: up 2026/05/05 17:03:26 -0500 (~ 11s ago)
Scaling an app on Heroku is equivalent to changing the number of running dynos. Scale the number of web dynos to zero:
$ heroku ps:scale web=0
$ heroku ps:wait
Access the app again by hitting refresh in your browser, or heroku open to open it in a web tab. You get an error message because you no longer have web dynos available to serve requests.
Scale it up again:
$ heroku ps:scale web=1
$ heroku ps:wait
By default, apps use Eco dynos if youโre subscribed to Eco. Otherwise, it defaults to Basic dynos. The Eco dynos plan is shared across all Eco dynos in your account and is recommended if you plan on deploying many small apps to Heroku. Eco dynos sleep if they donโt receive any traffic for half an hour. This sleep behavior causes a few seconds delay for the first request upon waking. Eco dynos consume from a monthly, account-level quota of eco dyno hours. As long as you havenโt exhausted the quota, your apps can continue to run.
To avoid dyno sleeping, upgrade to a Basic or higher dyno type as described in the Dyno Types article. Upgrading to at least Standard dynos allows you to scale up to multiple dynos per process type.
Install App Dependencies Locally
Heroku recognizes an app as a Python app by looking for key files. Including a requirements.txt in the root directory is one way we recognize your Python app.
The demo app you deployed already has a requirements.txt:
django>=6.0,<6.1
gunicorn>=25,<26
dj-database-url>=3,<4
whitenoise>=6,<7
The requirements.txt file lists the appโs dependencies. When you deploy an app on Heroku, the Python buildpack installs these dependencies using the pip install command.
To run the app locally, you must also install dependencies locally.
Before you do this, you must create and activate a virtual environment, also known as a venv. This environment lets you install the packages without affecting your system Python installation.
First, check that your local Python version:
$ python3 --version
If your Python version is older than 3.10 you must install a newer version of Python before creating a virtual environment. See the Python installation guides for macOS, Windows, and Linux.
Create a virtual environment inside the example app directory with this command:
$ python3 -m venv --upgrade-deps .venv
Next, activate the virtual environment:
If youโre on a Microsoft Windows system, activate with:
.\.venv\Scripts\activate
Or if youโre on a macOS/Linux system, activate with:
$ source .venv/bin/activate
For help with setting up a virtual environment, see the Python documentation.
Finally, install the dependencies into the newly created environment:
$ pip install -r requirements.txt
Installing the dependencies also installs their dependencies. View all installed packages using pip list:
$ pip list
Package Version
--------------- -------
asgiref 3.11.1
dj-database-url 3.1.2
Django 6.0.5
gunicorn 25.3.0
packaging 26.2
pip 26.1.1
sqlparse 0.5.5
whitenoise 6.12.0
After installing dependencies, you can run your app locally.
Run the App Locally
Start your application locally using the heroku local command, which is a part of the Heroku CLI.
If youโre on a Microsoft Windows system, run this:
$ heroku local --port 5006 -f Procfile.windows
Or if youโre on a macOS/Linux system, use the default Procfile by running:
$ heroku local --port 5006
Running the command starts up the local web server:
[OKAY] Loaded ENV .env File as KEY=VALUE Format
(node:11971) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
5:03:48 PM web.1 | [2026-05-05 17:03:48 -0500] [11983] [INFO] Starting gunicorn 25.3.0
5:03:48 PM web.1 | [2026-05-05 17:03:48 -0500] [11983] [INFO] Listening at: http://[::]:5006 (11983)
5:03:48 PM web.1 | [2026-05-05 17:03:48 -0500] [11983] [INFO] Using worker: gthread
5:03:48 PM web.1 | [2026-05-05 17:03:48 -0500] [11988] [INFO] Booting worker with pid: 11988
5:03:48 PM web.1 | [2026-05-05 17:03:48 -0500] [11988] [WARNING] Reloader is on. Use in development only!
If you see an error when running heroku local, check that you have installed the appโs dependencies locally and the virtual environment is still activated.
Just like Heroku, heroku local uses the Procfile to know what command to execute.
Open http://localhost:5006 with your web browser. You should see your app running locally.
To stop the app from running locally, go back to your terminal window and press Ctrl+C to exit.
Push Local Changes
In this step, you propagate a local change to the application to Heroku.
Modify requirements.txt to include an additional dependency on the requests package.
In file requirements.txt, on line 5 add:
requests
The file now looks like this:
django>=6.0,<6.1
gunicorn>=25,<26
dj-database-url>=3,<4
whitenoise>=6,<7
requests
Use pip to install the requests package via the updated requirements.txt file:
$ pip install -r requirements.txt
Modify hello/views.py to import the requests module and the Django HttpResponse class at the top of the file.
In file hello/views.py, on line 1 add:
import requests
from django.http import HttpResponse
Now modify the index method to use the module. Try replacing the current index method with the following code:
def index(request):
r = requests.get('https://httpbin.org/status/418', timeout=10)
return HttpResponse('<pre>' + r.text + '</pre>')
Now test again locally.
If youโre on a Microsoft Windows system, run this:
$ heroku local --port 5006 -f Procfile.windows
Or if youโre on a macOS/Linux system, use the default Procfile by running:
$ heroku local --port 5006
Visit your application at http://localhost:5006. If your changes worked, you will see the output of fetching https://httpbin.org/status/418:
-=[ teapot ]=-
_...._
.' _ _ `.
| ."` ^ `". _,
\_;`"---"`|//
| ;/
\_ _/
`"""`
If you see the error Internal Server Error in your browser, and the error ModuleNotFoundError: No module named 'requests' in the terminal log output, check that the requests package installed successfully.
Now deploy this local change to Heroku.
Almost every deploy to Heroku follows this same pattern. First, add the modified files to the local Git repository:
$ git add .
Now commit the changes to the repository:
$ git commit -m "Updated index view"
[main 268ba18] Updated index view
2 files changed, 3 insertions(+)
Now deploy as before:
$ git push heroku main
Finally, check that everything is working:
$ heroku open
Provision a Logging Add-on
Beyond databases, add-ons provide many additional services for your application. In this step, you provision a free add-on to store your appโs logs.
By default, Heroku stores 1500 lines of logs from your application, but the full log stream is available as a service. Several add-on providers have logging services that provide things such as log persistence, search, and email and SMS alerts.
In this step, you provision one of these logging add-ons, Papertrail.
Provision the Papertrail logging add-on:
$ heroku addons:create papertrail
Creating papertrail on dry-stream-67925... free
Provisioning has been successful
Created papertrail-flexible-17084
Run heroku addons:docs papertrail to view documentation.
The add-on is now deployed and configured for your app. You can list add-ons for your app with this command:
$ heroku addons
Add-on Plan Price Max Price State
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
papertrail (papertrail-flexible-17084) choklad free free created
โโ as PAPERTRAIL
The table above shows add-ons and the attachments to the current app (dry-stream-67925) or other apps.
To see this particular add-on in action, visit your applicationโs Heroku URL a few times. Each visit generates more log messages, which get routed to the Papertrail add-on. Visit the Papertrail console to see the log messages:
$ heroku addons:open papertrail
Your browser opens up a Papertrail web console, showing the latest log events. The interface lets you search and set up alerts.
Start a Console
You can run a command, typically scripts and applications that are part of your app, in a one-off dyno using the heroku run command. You can also run an interactive bash session in your appโs environment:
$ heroku run bash
Running bash on dry-stream-67925... starting, run.8776
Running bash on dry-stream-67925... connecting, run.8776
Running bash on dry-stream-67925... up, run.8776
~ $ ls -lah
total 80K
drwx------ 8 u20039 dyno 4.0K May 5 22:03 .
drwxr-xr-x 11 root root 4.0K Apr 22 14:59 ..
-rw------- 1 u20039 dyno 574 May 5 22:03 app.json
-rw------- 1 u20039 dyno 578 May 5 22:03 .env
drwx------ 3 u20039 dyno 4.0K May 5 22:03 gettingstarted
drwx------ 2 u20039 dyno 4.0K May 5 22:03 .github
-rw------- 1 u20039 dyno 106 May 5 22:03 .gitignore
-rw------- 1 u20039 dyno 4.9K May 5 22:03 gunicorn.conf.py
drwx------ 6 u20039 dyno 4.0K May 5 22:03 hello
drwx------ 3 u20039 dyno 4.0K May 5 22:03 .heroku
-rwx------ 1 u20039 dyno 671 May 5 22:03 manage.py
-rw------- 1 u20039 dyno 388 May 5 22:03 Procfile
-rw------- 1 u20039 dyno 39 May 5 22:03 Procfile.windows
drwx------ 2 u20039 dyno 4.0K May 5 22:03 .profile.d
-rw------- 1 u20039 dyno 424 May 5 22:03 project.toml
-rw------- 1 u20039 dyno 50 May 5 22:03 .python-version
-rw------- 1 u20039 dyno 2.3K May 5 22:03 README.md
-rw------- 1 u20039 dyno 131 May 5 22:03 requirements.txt
drwx------ 2 u20039 dyno 4.0K May 5 22:03 staticfiles
~ $ exit
exit
If you receive an error, Error connecting to process, configure your firewall.
Type exit to exit the shell.
Define Config Vars
Heroku lets you externalize configuration by storing data such as encryption keys or external resource addresses in config vars.
At runtime, we expose config vars as environment variables to the application.
To demonstrate this, modify hello/views.py so that the method repeats an action depending on the value of the TIMES environment variable.
In file hello/views.py, on line 1 add:
import os
Now modify the index method so that it repeats the word Hello! the number of times specified in the TIMES environment variable:
def index(request):
times = int(os.environ.get('TIMES', 3))
return HttpResponse('Hello! ' * times)
The heroku local command automatically sets up the environment based on the contents of the .env file in your local directory. In the top-level directory of your sample project, thereโs already a .env file that contains:
TIMES=2
Run the app with heroku local --port 5006 and visit http://localhost:5006 to see โHello!โ twice.
To set the config var on Heroku, execute the following:
$ heroku config:set TIMES=2
Setting TIMES and restarting dry-stream-67925... done, v4
TIMES: 2
View the appโs config vars using heroku config:
$ heroku config
TIMES: 2
...
To see this change in action, deploy your changed application to Heroku.
Provision a Database
The sample app requires a database. Provision a Heroku Postgres database, an add-on available through the Elements Marketplace. Add-ons are cloud services that provide out-of-the-box additional services for your application, such as logging, monitoring, databases, and more.
An essential-0 Postgres size costs $5 a month, prorated to the minute. At the end of this tutorial, we prompt you to delete your database to minimize costs.
$ heroku addons:create heroku-postgresql:essential-0
Creating heroku-postgresql:essential-0 on dry-stream-67925... ~$0.007/hour (max $5/month)
Database should be available soon
postgresql-slippery-98825 is being created in the background. The app will restart when complete...
Run heroku addons:info postgresql-slippery-98825 to check creation progress.
Run heroku addons:docs heroku-postgresql to view documentation.
You can wait for the database to provision by running this command:
$ heroku pg:wait
After that command exits, your Heroku app can access the Postgres database. The DATABASE_URL environment variable stores your credentials, which your app is configured to connect to. You can see all the add-ons provisioned with the addons command:
$ heroku addons
Add-on Plan Price Max Price State
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
heroku-postgresql (postgresql-slippery-98825) essential-0 ~$0.007/hour $5/month created
โโ as DATABASE
papertrail (papertrail-flexible-17084) choklad free free created
โโ as PAPERTRAIL
The table above shows add-ons and the attachments to the current app (dry-stream-67925) or other apps.
Use a Database
Listing the config vars for your app displays the URL that your app uses to connect to the database, DATABASE_URL:
$ heroku config
DATABASE_URL: postgres://xx:yyy@host:5432/d8slm9t7b5mjnd
HEROKU_POSTGRESQL_BROWN_URL: postgres://xx:yyy@host:5432/d8slm9t7b5mjnd
...
Heroku also provides a pg command that shows a lot more information:
$ heroku pg
=== DATABASE_URL
Plan: essential-0
Status: Available
Connections: unknown/20
PG Version: 17.9
Created: 2026-05-05 22:04
Data Size: unknown usage / 1 GB (In compliance)
Tables: 0/4000 (In compliance)
Fork/Follow: Unsupported
Rollback: Unsupported
Continuous Protection: On
Add-on: postgresql-slippery-98825
The example app you deployed already has database functionality. The example app you deployed already has database functionality, however, you must make two small changes to enable it. First, uncomment the psycopg line at the end of the requirements.txt file:
psycopg[binary]
This line ensures that the Postgres database adapter package installs during the build.
Next, uncomment the release process line at the end of the Procfile file:
release: ./manage.py migrate --no-input
This release process entry enables the Heroku Release Phase feature, and uses it to run any Django database migrations whenever the app deploys.
Deploy your changed application to Heroku using the same deployment process as before:
$ git add .
$ git commit -m "migrate database"
[main 1faafc5] migrate database
3 files changed, 3 insertions(+)
$ git push heroku
If the build fails with a settings.DATABASES is improperly configured error, check that you provisioned the database add-on before deploying.
View the output of the release code that ran automatically after the build to see Djangoโs database migrations:
$ heroku releases:output
Operations to perform:
Apply all migrations: hello
Running migrations:
Applying hello.0001_initial... OK
Visit the database demonstration page by running:
$ heroku open /db
This will show a simple page simple that updates with a timestamp every time you access it. Refresh the page to see it update:
Page View Report
May 5, 2026, 5:06 p.m.
May 5, 2026, 5:08 p.m.
The code to access the database is straightforward. It uses a simple Django model called Greeting that you can find in hello/models.py.
Whenever you visit the /db route of your app, the following method in the hello/views.py file invokes and creates a greeting. It then renders all the existing greetings:
def db(request):
# If you encounter errors visiting the `/db/` page on the example app, check that:
#
# When running the app on Heroku:
# 1. You have added the Postgres database to your app.
# 2. You have uncommented the `psycopg` dependency in `requirements.txt`, and the `release`
# process entry in `Procfile`, git committed your changes and re-deployed the app.
#
# When running the app locally:
# 1. You have run `./manage.py migrate` to create the `hello_greeting` database table.
greeting = Greeting()
greeting.save()
greetings = Greeting.objects.all()
return render(request, "db.html", {"greetings": greetings})
If you have Postgres installed locally, use the heroku pg:psql command to connect to the remote database and see all the rows:
$ heroku pg:psql
d8slm9t7b5mjnd=> \x
d8slm9t7b5mjnd=> select * from hello_greeting;
-[ RECORD 1 ]---------------------------
id | 1
when | 2026-05-05 17:06:08.071327-05
...
Read more about Heroku PostgreSQL.
You can use a similar technique to install MongoDB or Redis add-ons.
Delete Your App
Remove the app from your account. We only charge you for the resources you used.
This action permanently deletes your application and any add-ons attached to it.
$ heroku apps:destroy
You can confirm that your app is gone with this command:
$ heroku apps --all
Next Steps
You now know how to configure and deploy a Python app, view logs, and start a console.
To learn more, see: