Softotic
Back to insights
7 September 202623 min readPythonBackendDjangoAWS LambdaCloud Migration

Python 3.10 Reaches End of Life in October 2026: A Production Upgrade Plan

Python 3.10 reaches upstream end of life in October 2026. Use this production migration plan to choose Python 3.12, 3.13 or 3.14, test dependencies, and handle AWS Lambda, Google Cloud and Django compatibility safely.

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:

text
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 deadlines

When 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:

text
Upstream Python lifecycle
        ↓
Cloud/runtime vendor lifecycle
        ↓
Framework lifecycle
        ↓
Your own application support policy

Each layer can impose a separate deadline.

Google Cloud Functions / Cloud Run functions

Google Cloud's current runtime support table lists:

RuntimeDeprecationDecommission
Python 3.104 October 20264 April 2027
Python 3.1124 October 202724 April 2028
Python 3.122 October 20282 April 2029
Python 3.1310 October 202910 April 2030
Python 3.1410 October 203010 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:

MilestoneCurrent AWS date
Runtime deprecation31 October 2026
Block new function creation1 February 2027
Block function updates3 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:

VersionCurrent lifecycleUpstream EOL
Python 3.10SecurityOctober 2026
Python 3.11SecurityOctober 2027
Python 3.12SecurityOctober 2028
Python 3.13BugfixOctober 2029
Python 3.14BugfixOctober 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:

text
Django 5.2 + Python 3.10
        ↓
Django 5.2 + Python 3.12/3.13/3.14
        ↓
stabilise
        ↓
upgrade Django separately if needed

That 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:

text
framework support
+
Python runtime support
+
dependency support

as 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:

bash
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:

text
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.10

Create an inventory such as:

WorkloadRuntimePlatformOwnerCriticalityTarget
Public API3.10ECS/DockerBackendHigh3.13
Billing webhook3.10LambdaPlatformHigh3.13
PDF worker3.10CeleryBackendMedium3.12
Nightly import3.10Cloud Run functionDataMedium3.13
CI test image3.10GitHub ActionsDevExLow3.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:

bash
python -m pip list --outdated
python -m pip check

Then 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:

text
source code
+
declared dependencies
+
lockfile

to create a clean environment under the new interpreter.

For containers:

dockerfile
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:

text
3.10 → 3.11
3.11 → 3.12
3.12 → 3.13
3.13 → 3.14

depending 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:

dockerfile
FROM python:3.10-slim

to:

dockerfile
FROM python:3.13-slim

can 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:

text
apt-get install ...
native wheels
database clients
headless browser packages
image/video libraries
TLS integrations

Rebuild 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:

bash
python manage.py check
python manage.py makemigrations --check
python manage.py migrate --plan
python manage.py test

plus 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:

text
Web API
Celery worker
Celery Beat / scheduler
background consumers
management commands
event processors

For 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:

text
x86_64
or
arm64

but 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:

text
new function version
        ↓
target Python runtime
        ↓
integration tests
        ↓
small traffic weight / controlled invocation
        ↓
observe errors, duration, memory
        ↓
promote

Keep 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:

  1. inventory __INLINE_CODE_0__ functions;
  2. select a currently supported runtime;
  3. rebuild dependencies;
  4. deploy to staging;
  5. run event/HTTP integration tests;
  6. verify environment variables/secrets;
  7. check concurrency and timeout configuration;
  8. verify observability;
  9. 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:

text
application still runs
        ↓
team assumes migration can wait
        ↓
urgent hotfix needed in January
        ↓
build is blocked because runtime is unsupported

The 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.

Question3.123.133.14
Core framework supports it?CheckCheckCheck
Critical native dependencies have wheels?CheckCheckCheck
Cloud runtime supported?CheckCheckCheck
Internal libraries tested?CheckCheckCheck
Observability/security agents compatible?CheckCheckCheck
Support runwayGoodLongerLongest 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:

text
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 stability

Sometimes a dependency must be upgraded because the old release does not support the target interpreter. That is legitimate.

What you want to avoid is:

text
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 upgrade

all 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:

ComponentCurrentTargetVerified?Notes
Python3.10.213.13.xYes/No
Django5.2.xunchanged
Celery5.xunchanged
PostgreSQL driverversionversion
Redis clientversionversion
Pillowversionversionwheel available
Docker base3.10-slim3.13-slimOS changed?
Lambda layer3.10 build3.13 build
APM agentversionversion
CI image3.103.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:

text
Fresh environment
+ repository
+ documented secrets/config
+ dependency lock
= reproducible deploy

Plan rollback before deployment

A Python runtime rollback is often easier than a database migration, but it is not automatic.

Before release, answer:

  1. Is the previous container/function version still deployable?
  2. Did the new release also run irreversible database migrations?
  3. Did queued jobs change their payload format?
  4. Did pickled/serialised Python objects change?
  5. Can old and new workers consume the same queue safely?
  6. Did the application write new state the old runtime cannot understand?

A safer deployment separates backward-compatible schema changes from runtime cutover.

For example:

text
Deploy compatible database migration
        ↓
Deploy Python 3.13 application
        ↓
Observe
        ↓
Remove old compatibility code later

rather 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:

yaml
strategy:
  matrix:
    python-version:
      - "3.10"
      - "3.13"

Then:

text
Fix target-runtime failures
        ↓
Make 3.13 green
        ↓
Deploy staging on 3.13
        ↓
Promote production
        ↓
Remove 3.10 from CI

This 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:

text
Python
+ framework
+ dependencies
+ native wheels
+ container OS
+ workers
+ cloud runtime
+ deployment tooling
+ monitoring

That 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