Python 3.10 Reaches End of Life in October 2026: A Production Upgrade Plan
Python 3.10 is approaching the end of its upstream support window. The Python project lists the 3.10 branch in security-only support until October 2026, after which new upstream security fixes stop. The current security release is Python 3.10.21, released on 12 August 2026.
For production teams, the important point is that "Python 3.10 EOL" is not one universal shutdown date. Your language runtime, cloud platform, framework and deployment image can each have a different deadline. Google Cloud currently schedules its Python 3.10 runtime for deprecation on 4 October 2026, while AWS Lambda lists Python 3.10 deprecation for 31 October 2026 and later blocks for creating or updating functions.
The right response is therefore not to edit __INLINE_CODE_0__ and deploy. Inventory the real runtime estate, choose a supported target, rebuild dependencies, test native packages, validate framework compatibility, rehearse deployment and preserve rollback.
A practical sequence is:
Inventory every Python 3.10 workload
↓
Patch existing 3.10 environments
↓
Choose target Python version
↓
Rebuild dependencies and images
↓
Run tests + production-like workloads
↓
Validate cloud/framework constraints
↓
Deploy gradually
↓
Remove 3.10 before platform deadlinesWhen does Python 3.10 reach end of life?
The Python Developer's Guide currently lists Python 3.10 as a security branch with end of life in October 2026.
PEP 619, the Python 3.10 release schedule, says the branch receives irregular source-only security releases until approximately October 2026. Python 3.10 stopped receiving normal bug-fix releases years ago.
The latest release, Python 3.10.21, was published on 12 August 2026 and contains security fixes. Python.org also notes that:
- Python 3.10 is in security-fixes-only mode;
- releases are source-only;
- regular bug fixes no longer arrive; and
- Python 3.10.11 was the final 3.10 release with normal binary installers.
So if your production environment still uses an older 3.10 patch version, the immediate short-term action is to get onto the latest security release available through your distribution or platform while the migration proceeds.
But patching 3.10 is not a replacement for leaving 3.10.
Why the date differs between Python, AWS and Google Cloud
A common migration mistake is treating upstream EOL as if every hosting provider switches off the runtime on the same day.
They do not.
A useful way to think about it is:
Upstream Python lifecycle
↓
Cloud/runtime vendor lifecycle
↓
Framework lifecycle
↓
Your own application support policyEach layer can impose a separate deadline.
Google Cloud Functions / Cloud Run functions
Google Cloud's current runtime support table lists:
| Runtime | Deprecation | Decommission |
|---|---|---|
| Python 3.10 | 4 October 2026 | 4 April 2027 |
| Python 3.11 | 24 October 2027 | 24 April 2028 |
| Python 3.12 | 2 October 2028 | 2 April 2029 |
| Python 3.13 | 10 October 2029 | 10 April 2030 |
| Python 3.14 | 10 October 2030 | 10 April 2031 |
Those dates are platform-specific. A Google Cloud function that still executes after upstream EOL is not evidence that Python 3.10 is still upstream-supported.
AWS Lambda
AWS's current Lambda runtime support documentation lists Python 3.10 on Amazon Linux 2 with:
| Milestone | Current AWS date |
|---|---|
| Runtime deprecation | 31 October 2026 |
| Block new function creation | 1 February 2027 |
| Block function updates | 3 March 2027 |
AWS also notes that Amazon Linux 2 itself reached its scheduled end of life on 30 June 2026, while selected Lambda runtimes including Python 3.10 continue receiving critical/important AL2 security patches until their listed runtime deprecation dates.
The implication is important:
A cloud provider grace period is a migration window, not an extension of upstream Python support.
Which Python version should you upgrade to?
For a production migration in September 2026, the reasonable targets are normally Python 3.12, 3.13 or 3.14, depending on framework and dependency compatibility.
The Python project's current support table lists:
| Version | Current lifecycle | Upstream EOL |
|---|---|---|
| Python 3.10 | Security | October 2026 |
| Python 3.11 | Security | October 2027 |
| Python 3.12 | Security | October 2028 |
| Python 3.13 | Bugfix | October 2029 |
| Python 3.14 | Bugfix | October 2030 |
Python 3.15 is still pre-release as of September 2026, so it should not be the default production migration target merely because it is newest.
For many production systems:
- Python 3.12 is a conservative target with broad ecosystem maturity and several years of support remaining.
- Python 3.13 gives a longer runway and is appropriate when your dependencies already support it.
- Python 3.14 gives the longest current stable support window, but dependency compatibility should be verified before choosing it.
Avoid Python 3.11 as a fresh 2026 migration target unless there is a concrete compatibility constraint. Its upstream support ends in October 2027, so the migration runway is comparatively short.
The best target is the newest stable version your whole application stack supports, not merely the newest interpreter you can install.
Django projects need a framework decision too
Python runtime upgrades and Django upgrades are related but should not be collapsed into one uncontrolled change.
Current Django documentation says:
- Django 5.2 LTS supports Python 3.10 through Python 3.14;
- Django 6.0 supports Python 3.12, 3.13 and 3.14;
- Django 6.1 supports Python 3.12, 3.13 and 3.14.
Django's own installation guidance says Python versions that have reached upstream end of life should not be used with Django.
This creates several realistic migration paths.
Django 5.2 on Python 3.10
You do not need to upgrade Django just to leave Python 3.10.
A lower-risk sequence can be:
Django 5.2 + Python 3.10
↓
Django 5.2 + Python 3.12/3.13/3.14
↓
stabilise
↓
upgrade Django separately if neededThat reduces the number of moving pieces in one deployment.
Older Django project
If the project is on an unsupported Django version, the problem is broader.
Do not hide an obsolete framework behind a Python runtime change. Plan:
framework support
+
Python runtime support
+
dependency supportas a coordinated modernisation project.
Moving to Django 6.x
If the business already intends to move to Django 6.0 or 6.1, the Python upgrade can be combined deliberately because Django 6.x requires Python 3.12 or newer.
But combining them increases the regression surface. Use a complete test suite and a production-like rehearsal.
Step 1: find every Python 3.10 workload
Do not search only the main API repository.
Python can be hiding in:
- Django or FastAPI services;
- AWS Lambda functions;
- Google Cloud Functions;
- Cloud Run containers;
- Docker base images;
- Celery workers;
- Airflow jobs;
- data-processing scripts;
- scheduled cron jobs;
- CI/CD images;
- Terraform provisioning helpers;
- serverless deployment packages;
- notebooks used in operational pipelines;
- internal admin scripts;
- image-processing workers;
- machine-learning inference services.
Search source repositories:
grep -R "python:3\.10" .
grep -R "python3\.10" .
grep -R "3\.10" pyproject.toml requirements*.txt runtime.txt Dockerfile* .github/ .Also inspect deployment configuration rather than relying only on source.
Examples:
AWS Lambda runtime = python3.10
Google function runtime = python310
Docker FROM python:3.10-slim
Heroku runtime.txt = python-3.10.x
CI setup-python version = 3.10Create an inventory such as:
| Workload | Runtime | Platform | Owner | Criticality | Target |
|---|---|---|---|---|---|
| Public API | 3.10 | ECS/Docker | Backend | High | 3.13 |
| Billing webhook | 3.10 | Lambda | Platform | High | 3.13 |
| PDF worker | 3.10 | Celery | Backend | Medium | 3.12 |
| Nightly import | 3.10 | Cloud Run function | Data | Medium | 3.13 |
| CI test image | 3.10 | GitHub Actions | DevEx | Low | 3.13 |
The output is your migration scope.
Step 2: identify dependency blockers before changing the interpreter
The most common upgrade failures are not caused by pure Python syntax.
They are caused by dependencies.
Pay particular attention to packages that include or depend on native code:
- __INLINE_CODE_0__;
- __INLINE_CODE_0__;
- __INLINE_CODE_0__;
- __INLINE_CODE_0__;
- __INLINE_CODE_0__;
- Pillow;
- __INLINE_CODE_0__;
- __INLINE_CODE_0__;
- __INLINE_CODE_0__;
- geospatial libraries;
- ML frameworks;
- proprietary binary wheels.
For each production project:
python -m pip list --outdated
python -m pip checkThen build the complete environment under the proposed target Python in CI.
If you use __INLINE_CODE_0__, Poetry, pip-tools or another lockfile workflow, regenerate or validate the lock against the new interpreter rather than assuming a Python 3.10 lock is universally portable.
The question is not:
Does package X support Python 3.13?
It is:
Does the exact combination of versions in our lockfile resolve, install and behave correctly on Python 3.13 for our operating system and architecture?
Step 3: rebuild dependencies instead of copying an old virtualenv
Never carry a Python 3.10 virtual environment into a new interpreter.
Virtual environments can contain:
- interpreter-specific paths;
- compiled extension modules;
- ABI-specific wheels;
- cached packages;
- generated entry points.
Use:
source code
+
declared dependencies
+
lockfileto create a clean environment under the new interpreter.
For containers:
FROM python:3.13-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .Then run the application tests in that same image.
Do not prove compatibility on a developer laptop and deploy a differently built production container.
Step 4: test language-level behavioural changes
A Python upgrade across several major versions crosses multiple sets of changes.
Review the official "What's New" and porting notes for every version crossed:
3.10 → 3.11
3.11 → 3.12
3.12 → 3.13
3.13 → 3.14depending on your target.
Focus on code that relies on:
- deprecated standard-library APIs;
- removed modules;
- exception behaviour;
- typing internals;
- import behaviour;
- __INLINE_CODE_0__;
- multiprocessing;
- C-extension interfaces;
- packaging/build assumptions;
- locale/timezone behaviour;
- cryptographic/TLS dependencies.
Do not read every release note line with equal weight. Search your codebase for affected APIs and let tests prove application behaviour.
Step 5: treat container base images as a separate dependency
Changing:
FROM python:3.10-slimto:
FROM python:3.13-slimcan change more than Python.
Your image may also move across:
- Debian releases;
- OpenSSL versions;
- libc versions;
- compiler/toolchain versions;
- system package names;
- CA certificate bundles.
That can expose issues in:
apt-get install ...
native wheels
database clients
headless browser packages
image/video libraries
TLS integrationsRebuild the container from scratch and scan/test the resulting image.
Avoid treating a base-image change as a text substitution.
Step 6: test database drivers and connection behaviour
Backend applications should explicitly test:
- PostgreSQL/MySQL driver import;
- TLS connections;
- migrations;
- connection pooling;
- prepared statements;
- transaction handling;
- async drivers;
- failover/reconnect behaviour.
For a Django app, run:
python manage.py check
python manage.py makemigrations --check
python manage.py migrate --plan
python manage.py testplus the project's normal integration tests.
For a production API, test representative queries against a staging database with realistic extensions and authentication.
Step 7: test workers separately from the web process
A web app can pass its smoke test while a worker fleet is broken.
Treat these as separate deployables:
Web API
Celery worker
Celery Beat / scheduler
background consumers
management commands
event processorsFor Celery or other background systems, verify:
- worker starts under target Python;
- task autodiscovery succeeds;
- serialisation works;
- broker client supports the target interpreter;
- retries behave correctly;
- scheduled tasks execute;
- process shutdown/restart is clean;
- native dependencies load inside worker images.
If web and worker images share a base image, do not assume shared packaging guarantees shared runtime behaviour.
AWS Lambda: how to migrate Python 3.10 safely
AWS currently lists Python 3.10 runtime deprecation for 31 October 2026.
A Lambda migration should include more than updating the runtime dropdown.
Inventory layers
Lambda Layers can contain Python-version-specific packages.
A function can move to Python 3.13 while a layer still contains a compiled wheel built for 3.10.
Check:
- shared internal layers;
- third-party layers;
- Lambda extensions;
- compiled dependencies;
- container base images.
Build packages for the Lambda execution environment
If you package native dependencies, build wheels compatible with Lambda's target operating system and architecture.
Do not upload packages compiled only for your Mac or Windows development machine.
Test architecture too
An upgrade is a good moment to verify whether the function uses:
x86_64
or
arm64but avoid changing architecture and Python version in the same deployment unless there is a reason and benchmarks/tests cover both.
Use aliases or staged traffic where possible
For business-critical functions:
new function version
↓
target Python runtime
↓
integration tests
↓
small traffic weight / controlled invocation
↓
observe errors, duration, memory
↓
promoteKeep the previous version available long enough to support rollback, subject to your security and deployment policy.
Google Cloud Functions: deprecation is earlier than AWS
Google Cloud currently lists Python 3.10 deprecation on 4 October 2026, which arrives before AWS Lambda's current 31 October runtime deprecation date.
So a company using both platforms should not create one vague ticket saying:
Upgrade Python sometime in October.
Use platform-specific deadlines.
For Google Cloud:
- inventory __INLINE_CODE_0__ functions;
- select a currently supported runtime;
- rebuild dependencies;
- deploy to staging;
- run event/HTTP integration tests;
- verify environment variables/secrets;
- check concurrency and timeout configuration;
- verify observability;
- cut over before the platform deprecation window becomes urgent.
If a Cloud Function has not been touched for years, also inspect whether its generation, event trigger and base image should be modernised rather than moving only the runtime number.
Heroku has a different removal date again
Heroku has already marked Python 3.10 as deprecated in its buildpack lifecycle.
Heroku's current deprecation notice says Python 3.10 support will be removed from the Python buildpack on 6 January 2027. Existing Python 3.10 apps can continue running, but deployments/builds will require a newer Python version.
That creates a classic trap:
application still runs
↓
team assumes migration can wait
↓
urgent hotfix needed in January
↓
build is blocked because runtime is unsupportedThe safe time to discover build-system compatibility is before an emergency deployment.
How should you choose between Python 3.12, 3.13 and 3.14?
Use a compatibility scorecard rather than choosing from support-window length alone.
| Question | 3.12 | 3.13 | 3.14 |
|---|---|---|---|
| Core framework supports it? | Check | Check | Check |
| Critical native dependencies have wheels? | Check | Check | Check |
| Cloud runtime supported? | Check | Check | Check |
| Internal libraries tested? | Check | Check | Check |
| Observability/security agents compatible? | Check | Check | Check |
| Support runway | Good | Longer | Longest current stable |
A useful rule:
Choose Python 3.12 when
- compatibility is the dominant constraint;
- a critical vendor or package has not certified newer versions;
- you need a lower-risk production move now.
Choose Python 3.13 when
- your stack supports it;
- you want a longer support window;
- it has passed realistic workload testing.
Choose Python 3.14 when
- every production dependency supports it;
- your cloud/platform deployment path supports it;
- you have tested the application rather than assuming "stable" means ecosystem-ready.
Do not select a version based only on a synthetic benchmark.
Should you combine the Python upgrade with dependency upgrades?
Usually, minimise unrelated change.
A useful strategy is:
Phase A
Bring current Python 3.10 environment to healthy dependency/security state
Phase B
Move to target Python with the smallest necessary dependency changes
Phase C
Modernise unrelated packages after runtime stabilitySometimes a dependency must be upgraded because the old release does not support the target interpreter. That is legitimate.
What you want to avoid is:
Python 3.10 → 3.14
Django 5.2 → 6.1
Celery major upgrade
psycopg2 → psycopg 3
Redis client major upgrade
Docker distribution change
database major upgradeall in one production release without a compelling reason.
That creates a debugging fog where any failure can come from six independent migrations.
Build a compatibility matrix before touching production
A simple table prevents accidental omissions:
| Component | Current | Target | Verified? | Notes |
|---|---|---|---|---|
| Python | 3.10.21 | 3.13.x | Yes/No | |
| Django | 5.2.x | unchanged | ||
| Celery | 5.x | unchanged | ||
| PostgreSQL driver | version | version | ||
| Redis client | version | version | ||
| Pillow | version | version | wheel available | |
| Docker base | 3.10-slim | 3.13-slim | OS changed? | |
| Lambda layer | 3.10 build | 3.13 build | ||
| APM agent | version | version | ||
| CI image | 3.10 | 3.13 |
The matrix should include every component capable of breaking the deployment, not every package in __INLINE_CODE_0__.
Test the runtime under production-like load
Unit tests can prove business logic. They do not fully prove runtime behaviour.
For a high-traffic service, compare the old and new environment under representative load.
Measure:
- request latency;
- CPU;
- memory;
- startup time;
- worker throughput;
- error rate;
- database connection use;
- cold-start latency for serverless functions;
- queue processing rate.
Do not promise that a newer Python version will improve performance until your workload says so.
A migration succeeds when it preserves or improves the service's required behaviour, not when a microbenchmark goes faster.
Watch for build failures that production has been hiding
A runtime migration frequently exposes a more embarrassing problem: the application is not reproducibly buildable.
Examples:
- requirements file is incomplete;
- production server has manually installed packages;
- an old private package index no longer works;
- a wheel vanished;
- a Git dependency points to a deleted branch;
- system libraries are undocumented;
- deployment requires a developer's local file.
That is not a reason to abandon the migration.
It is evidence that the deployment process needed repair.
Use the upgrade to make this invariant true:
Fresh environment
+ repository
+ documented secrets/config
+ dependency lock
= reproducible deployPlan rollback before deployment
A Python runtime rollback is often easier than a database migration, but it is not automatic.
Before release, answer:
- Is the previous container/function version still deployable?
- Did the new release also run irreversible database migrations?
- Did queued jobs change their payload format?
- Did pickled/serialised Python objects change?
- Can old and new workers consume the same queue safely?
- Did the application write new state the old runtime cannot understand?
A safer deployment separates backward-compatible schema changes from runtime cutover.
For example:
Deploy compatible database migration
↓
Deploy Python 3.13 application
↓
Observe
↓
Remove old compatibility code laterrather than coupling the interpreter upgrade to an irreversible schema transition.
Do not share Python pickles across runtime boundaries casually
If queues, caches or files contain Python __INLINE_CODE_0__ objects, test them explicitly.
Pickle is tightly coupled to Python object definitions and is unsafe for untrusted data.
For distributed systems, prefer explicit interoperable formats such as:
- JSON;
- MessagePack where appropriate;
- Protobuf;
- well-defined database records.
A Python upgrade is a good opportunity to identify hidden interpreter-coupled serialisation in worker queues or caches.
A practical CI migration strategy
Add the target Python before removing 3.10.
For example:
strategy:
matrix:
python-version:
- "3.10"
- "3.13"Then:
Fix target-runtime failures
↓
Make 3.13 green
↓
Deploy staging on 3.13
↓
Promote production
↓
Remove 3.10 from CIThis creates a temporary compatibility bridge.
Do not leave the matrix permanently if 3.10 is no longer a supported production target. Once migration is complete, keeping old-runtime CI green can consume effort without business value.
Security scanning must follow the new image too
Runtime migration changes your software supply chain.
After rebuilding:
- scan the new container;
- review OS package vulnerabilities;
- scan Python dependencies;
- verify TLS/CA behaviour;
- check base-image provenance;
- confirm secrets are not baked into layers;
- confirm least-privilege execution.
A green Python test suite does not prove the replacement image has the same security posture.
A four-week migration plan
For a conventional backend that is still on Python 3.10 in early September 2026:
Week 1: inventory and target selection
- locate every 3.10 runtime;
- update current 3.10 patch levels where applicable;
- choose Python 3.12, 3.13 or 3.14;
- identify platform deadlines;
- identify native/binary dependencies.
Week 2: build and test
- add target Python to CI;
- rebuild lockfiles where required;
- build fresh containers/layers;
- fix compatibility failures;
- run unit and integration tests.
Week 3: production-like validation
- deploy staging;
- test database and external integrations;
- test workers/serverless functions;
- benchmark representative workload;
- exercise rollback.
Week 4: production cutover
- deploy low-risk workloads first;
- observe errors, memory and latency;
- progressively move critical services;
- keep rollback versions available;
- remove Python 3.10 from active deployment configuration.
Google Cloud users should prioritise workloads with the 4 October 2026 deprecation date.
What not to do
Do not wait for the application to stop running
End of life normally means support and security fixes stop, not that the interpreter self-destructs.
Do not confuse cloud grace periods with upstream support
AWS, Google Cloud and Heroku publish their own lifecycle dates.
Do not migrate only the web server
Workers, scheduled jobs, functions, layers and CI can remain on 3.10 unnoticed.
Do not copy an old virtualenv
Rebuild dependencies under the target interpreter.
Do not select Python 3.14 solely because it is newest
Verify every critical dependency and hosting platform.
Do not combine five unrelated major upgrades without a reason
Keep the change surface explainable.
Do not assume pure unit tests are enough
Test container builds, native wheels, database drivers, workers and deployment systems.
Do not pin an old patch release after the migration
Use an intentional patch-update process so supported runtimes continue receiving security fixes.
A production migration checklist
- □Every Python 3.10 service, worker, function and script is inventoried.
- □Current 3.10 environments are patched while migration is underway.
- □Target Python version has a sufficient support runway.
- □Framework compatibility is confirmed.
- □Native/binary dependencies have compatible builds.
- □Lockfiles resolve under the target interpreter.
- □Fresh containers/virtualenvs build reproducibly.
- □CI runs the target Python.
- □Database drivers and migrations are tested.
- □Background workers and schedulers are tested.
- □AWS Lambda layers are rebuilt where relevant.
- □Google Cloud runtime configuration is updated where relevant.
- □Monitoring/APM agents support the target runtime.
- □Staging uses the same target runtime as production.
- □Representative load/performance has been measured.
- □Rollback version is known and tested.
- □Irreversible schema changes are separated where practical.
- □Production telemetry is reviewed after cutover.
- □Python 3.10 is removed from deployable configuration after migration.
FAQs
When does Python 3.10 reach end of life?
The Python project currently lists Python 3.10 security support through October 2026. PEP 619 describes source-only security fixes until approximately October 2026. After upstream end of life, normal new Python 3.10 security fixes stop.
What is the latest Python 3.10 release?
Python.org lists Python 3.10.21, released on 12 August 2026, as the current 3.10 security release at the time of writing.
When does AWS Lambda deprecate Python 3.10?
AWS currently lists 31 October 2026 as the Python 3.10 Lambda runtime deprecation date, followed by planned blocks on creating new Python 3.10 functions on 1 February 2027 and updating them on 3 March 2027.
When does Google Cloud deprecate Python 3.10 functions?
Google Cloud's current runtime table lists Python 3.10 deprecation on 4 October 2026 and decommission on 4 April 2027 for Cloud Run functions/Cloud Functions runtime support.
Which Python version should replace 3.10?
For most production systems, evaluate Python 3.12, 3.13 or 3.14. Choose the newest stable version supported by your framework, cloud platform, native dependencies and operational tooling. Python 3.11 has a shorter remaining support window and is usually a less attractive new migration target in late 2026.
Do I need to upgrade Django when leaving Python 3.10?
Not necessarily. Django 5.2 LTS currently supports Python 3.10 through 3.14. A Django 5.2 project can move from Python 3.10 to a newer supported Python version first and upgrade Django separately. Django 6.x requires Python 3.12 or newer.
Conclusion
Python 3.10 end of life is a language-runtime deadline, but production systems do not consist of a language runtime alone.
The real migration surface is:
Python
+ framework
+ dependencies
+ native wheels
+ container OS
+ workers
+ cloud runtime
+ deployment tooling
+ monitoringThat is why "change 3.10 to 3.13" can either be a safe maintenance release or a surprisingly large incident.
The durable approach is to inventory first, choose a target with enough support runway, rebuild the environment from declared dependencies, test every deployable independently, follow platform-specific dates and stage the production rollout while rollback is still easy.
For teams using Google Cloud, the current 4 October 2026 Python 3.10 deprecation date makes this an immediate September task. AWS Lambda's current 31 October date provides slightly more room, but not enough to justify waiting for an emergency.
If your Python backend needs a runtime upgrade alongside Django, worker, API or cloud deployment changes, Softotic's custom software development service can help structure the migration, while web application development can cover the application and deployment layer.
Sources and references
- Python Developer's Guide: Status of Python versions
- PEP 619: Python 3.10 Release Schedule
- Python.org: Python 3.10.21
- AWS Lambda: Runtime support
- Google Cloud: Cloud Run functions runtime support
- Django 6.0 release notes and Python compatibility
- Django 5.2 release notes and Python compatibility
- Heroku: Python 3.10 support is deprecated