all posts

Best Jupyter notebook hosting platforms in 2026

Ajay Kumar··10 min read

Every notebook platform is one !pip install away from being a general-purpose code-execution API. That is the whole reason this decision is harder than it looks. On the surface you are picking a place to store some .ipynb files and a UI to run cells in. Underneath, you are choosing who runs the kernel, what that kernel can reach, what it costs while somebody stares at a chart for forty minutes, and what happens the day a user pastes in code they found on the internet.

I build PandaStack, which puts each notebook kernel in its own Firecracker microVM, so treat this as a vendor's roundup and weight it accordingly. The way I try to keep it honest: specific numbers only where I can stand behind them (which means only for our own system), and every third-party platform described qualitatively from its own public documentation. Pricing, GPU SKUs, and quotas in this market change faster than any blog post can track — verify all of those against each vendor's current docs before you commit to anything.

Disclosure: PandaStack is my company. I have included it in the list because it genuinely belongs in the isolation conversation, and I have tried to be equally clear about what it is not — it has no GPU story worth bragging about, and it is not a collaborative notebook UI. It is the kernel layer underneath one. If what you want is a beautiful multiplayer notebook editor, several tools below beat us at that outright, and you should buy one of them.

The six axes that actually decide this

Feature matrices for notebook platforms are nearly useless, because they all check the same boxes: run Python, render matplotlib, install packages, share a link. The differences that determine whether you regret the choice in eighteen months live in six places.

  1. Who runs the kernel, and how isolated is it? A kernel process on a shared host with other users' kernels is a completely different security posture from a kernel that owns a virtual machine. This is the axis that most quietly constrains everything else.
  2. GPU access. Whether you can get one at all, whether you can get the class you need, whether the queue is measured in seconds or hours, and whether attaching one requires moving to a different plan or a different product.
  3. Idle cost and scale-to-zero. Notebook work is bursty by nature — minutes of compute, hours of reading. Whether the platform bills wall-clock for an idle kernel or drops it to zero is often a bigger line item than the compute rate.
  4. Persistence of state and data. Three separate things that get conflated: the notebook file, the environment (installed packages), and the working data on disk. Some platforms persist all three, some persist one, and finding out which after a session dies is expensive.
  5. Collaboration. Real-time multiplayer editing, comments, scheduled runs, publishable dashboards, and review workflow. This is where the commercial notebook products earn their money and where raw infrastructure does not compete.
  6. Untrusted execution. Can you hand a notebook environment to a student, a candidate, a customer, or an AI agent, and be relaxed about what runs in it? If the answer is no, several otherwise excellent options are off your list entirely.

Start with the kernel question

A Jupyter kernel is a process that executes arbitrary code with the privileges of whatever it runs inside. That statement is the entire security model, and everything else is a question of what wraps it. Broadly there are three wrappers in production use.

  • Shared host, separate processes. The classic single-node JupyterHub with a local spawner: every user's kernel is a Unix process on the same machine, separated by user accounts and maybe cgroups. Cheap, simple, and it means one user's runaway job is everyone's problem.
  • Container per user. A Kubernetes or Docker spawner gives each user their own namespaces, cgroups, and filesystem view. A large improvement, and still one shared host kernel underneath — a kernel-level escape is a host compromise, and resource isolation is only as good as the limits you remembered to set.
  • Virtual machine per user. Each kernel gets its own guest kernel, isolated by hardware virtualization. Guest code never touches the host kernel directly; the exposed surface is the much smaller virtual machine monitor. This is the bar for arbitrary untrusted notebooks, and it used to be too slow and too expensive to give to every user — microVMs are what changed that.

The classic failure mode of the shared-host model is not a sophisticated attack. It is a first-year student who writes while True: os.fork() in cell three, and takes down the lab for the other two hundred people mid-assessment. No amount of goodwill fixes that; only a resource boundary does. I have written up the multi-tenant version of this problem in /blog/sandbox-vs-jupyterhub-multi-tenant.

JupyterHub (self-hosted)

JupyterHub is the reference implementation of multi-user Jupyter and the thing most other options are implicitly compared against. It is open source, endlessly configurable, and the spawner abstraction means you can back it with local processes, Docker, Kubernetes, or a batch scheduler. If you have on-premise hardware — a GPU cluster a department already owns, or data that legally cannot leave the building — this is usually the correct answer and there is not a close second.

The honest limitation is that JupyterHub is a framework, not a product. The isolation you get is entirely the isolation your spawner configuration provides, and the default configurations are much weaker than people assume. Add the operational reality — authentication, storage, image builds, upgrades, idle culling, and the pager — and 'we'll just run JupyterHub' is a staffing decision, not an install. Best for: institutions with existing hardware and someone whose job includes this. Limitation: the security posture and the uptime are both yours.

# The self-hosted JupyterHub reality check, run on the box before you commit

# 1. How many kernels share this host kernel right now?
ps -eo user,pid,pcpu,pmem,args | grep -c '[i]pykernel_launcher'

# 2. Do the spawned kernels actually have limits, or did we just hope?
systemd-cgls /sys/fs/cgroup | grep -A2 jupyter
cat /sys/fs/cgroup/user.slice/*/memory.max 2>/dev/null | sort -u

# 3. What stops one notebook from reading another user's data?
ls -ld /home/*/work | head

# 4. The test nobody runs until the incident review asks for it:
#    fork-bomb one account and see whether anyone else notices.
#    Do this in staging. Genuinely, do this in staging.

Google Colab

Colab is the default on-ramp for the entire field, and for good reason: zero setup, a link you can send to anyone, and GPU access available to casual users without a procurement conversation. For teaching material, reproducible tutorials, quick experiments, and anything you want a stranger to be able to run in thirty seconds, it is extremely hard to beat.

The limitations are the ones that come with a free-tier-first product: sessions are ephemeral and can be reclaimed, the environment resets, resource availability varies by demand, and the whole thing is deliberately not a place to run production or scheduled work. Availability and pricing tiers change regularly — check Google's current documentation rather than any secondhand summary, including this one. Best for: teaching, sharing, and casual GPU experimentation. Limitation: not a durable or governable place for real workloads.

Deepnote

Deepnote is a collaborative notebook product rather than a hosting layer — real-time multiplayer editing, comments, a much nicer data-source and scheduling story than raw Jupyter, and output that is presentable to people who do not want to see the code. If your bottleneck is that analysts cannot easily share work with stakeholders, this class of tool solves your actual problem.

The trade is that you are buying into a product's environment model rather than a plain kernel you control, and heavy custom-infrastructure requirements fit less naturally. Compute options and pricing tiers move; verify against their current docs. Best for: analytics teams where collaboration and presentation matter more than raw infrastructure control. Limitation: less suited to arbitrary custom runtimes or untrusted third-party code.

Hex

Hex sits further along the same trajectory as Deepnote: notebook-adjacent, but with a strong opinion that the deliverable is an interactive app or report rather than a scrolling .ipynb. The mixed SQL-and-Python workflow and the publish-as-app path are the reasons teams choose it, and it genuinely changes how analysts share work.

It is also further from being a general compute platform. If your workload is 'train a model on eight GPUs' or 'run this untrusted notebook from an external contributor', it is the wrong shape of tool — that is not a flaw, it is a product decision. Best for: analytics teams shipping decision-support apps to non-technical stakeholders. Limitation: not a general-purpose kernel host.

Databricks notebooks

If your data already lives in a lakehouse and your jobs are Spark jobs, Databricks notebooks are less a choice than a consequence, and a good one. The notebook is tightly wired to cluster management, job scheduling, governance, and the catalog, which is exactly what you want when the notebook is a front end for a large distributed compute engine.

For a small team that just wants a Python kernel with pandas, it is a very large amount of platform to adopt, and cluster startup and cost management become their own discipline. Best for: organisations already committed to the lakehouse. Limitation: heavy, and the notebook experience is inseparable from the platform around it.

Amazon SageMaker Studio

SageMaker Studio is the AWS-native answer: notebooks that sit inside IAM, VPCs, and the rest of the AWS control surface, with a path from experiment to training job to endpoint that stays inside one account boundary. When compliance requires everything in your own AWS account with auditable access control, this is a strong default.

The cost is the usual AWS cost: configuration surface, instance-type decisions, and a bill that rewards people who remember to shut things down. Instance families and pricing change often — read the current AWS documentation. Best for: teams already governed by AWS. Limitation: complexity, and idle instances that quietly bill.

Modal comes at notebooks from the serverless-compute direction: define functions in Python, get them executed on managed infrastructure with GPUs attached on demand, and treat the notebook as one interface to that rather than the centre of the world. For bursty GPU work — fine-tuning runs, batch inference — the model is a genuinely good fit, and idle cost is structurally low because you are not holding a machine.

Its isolation is gVisor-based, which is a real step up from a plain container and a different bet from full hardware virtualization; worth understanding rather than glossing. And a function-first mental model is an adjustment if what you wanted was a long-lived interactive kernel with a warm dataframe in memory. Best for: GPU-bursty Python workloads. Limitation: not primarily a notebook product.

Binder

Binder does one thing beautifully: turn a public repository into a runnable notebook environment from a URL, with no account. For reproducible papers, workshop material, and library documentation you want people to actually execute, nothing else has the same friction profile.

It is explicitly not for private data, long-running work, or anything you need to be reliably available — the public service runs on donated capacity and sessions are ephemeral by design. You can self-host BinderHub, at which point you have inherited the JupyterHub operational story above. Best for: public, reproducible, disposable. Limitation: no persistence, no privacy guarantees, no availability promise.

GitHub Codespaces

Codespaces is a development environment that happens to run notebooks well, via the VS Code notebook interface and a devcontainer that pins your environment in the repository. If your notebooks live alongside application code and you want one reproducible environment definition for both, this is a tidy answer, and the repo-native environment spec is a real advantage over platforms where the environment is a UI setting.

It is a per-developer dev environment, not a multi-tenant notebook service — there is no natural model for handing one to two hundred students or to an anonymous visitor, and it is container-based rather than VM-per-user. Best for: engineering teams whose notebooks live in a code repository. Limitation: not a multi-tenant or untrusted-execution platform.

PandaStack (ours — per-user microVM kernels)

This is my project, so here is the precise claim and nothing more. PandaStack gives each kernel its own Firecracker microVM: its own guest kernel, its own memory, its own network namespace drawn from 16,384 pre-allocated /30 subnets per host. The thing that makes this practical rather than theoretical is the boot path — there is no warm pool of idle VMs, and every create restores a pre-baked snapshot, which lands at 179ms p50 and 203ms p99 (the restore step itself is roughly 49ms). Only the very first spawn of a brand-new template cold-boots, at around 3 seconds. Because a kernel is that cheap to create, you can afford one per user, per assignment, or per agent request, and destroy it afterwards.

The second useful property is forking. A running kernel can be cloned copy-on-write — 400 to 750ms on the same host, 1.2 to 3.5 seconds across hosts — so you can warm one environment with dependencies installed and a dataset loaded, then branch it per student or per experiment without re-running setup. There is also managed Postgres on the same substrate if a notebook needs a real database behind it (creating one takes 30 to 90 seconds, since it is a whole machine booting).

Now the parts I am not going to oversell. PandaStack has no meaningful GPU story — if you need accelerators, take one of the platforms above and do not let me talk you out of it. It is also not a collaborative notebook UI: there is no multiplayer editor, no comment threads, no publish-as-dashboard. It is the isolated kernel and compute layer you put underneath a notebook front end — including JupyterLab itself, which runs perfectly happily in a microVM. Best for: multi-tenant or untrusted notebook execution where per-user isolation is the requirement. Limitation: no GPUs, and you bring your own notebook experience.

# One microVM kernel per user, created on demand, destroyed after.
from pandastack import Sandbox

# persistent=True keeps the machine (and the user's working files) between
# sessions; drop it for a genuinely disposable per-assignment kernel.
sbx = Sandbox.create(template="code-interpreter", persistent=True)

# Push the user's notebook (or a student's submission) into their own VM.
sbx.filesystem.write("/home/user/analysis.py", open("analysis.py").read())

# Whatever this code does, it does it inside its own guest kernel.
# A fork bomb here ends one VM, not the lab.
result = sbx.exec("python3 /home/user/analysis.py", timeout_seconds=300)
print(result.stdout, result.exit_code)

# Tear it down. The next create is another ~180ms snapshot restore.
sbx.kill()

The field at a glance

  • JupyterHub (self-hosted) — isolation: whatever your spawner gives you, from shared processes to containers. idle cost: you pay for the hardware regardless unless you built culling. best for: institutions with their own machines and an operator.
  • Google Colab — isolation: managed and opaque, ephemeral sessions. idle cost: effectively none to you, since sessions get reclaimed. best for: teaching, sharing, casual GPU experiments.
  • Deepnote — isolation: managed containerised environments. idle cost: tier-dependent, generally with idle shutdown. best for: collaborative analytics with a presentable output.
  • Hex — isolation: managed, product-defined. idle cost: tier-dependent. best for: turning analyses into interactive apps for stakeholders.
  • Databricks notebooks — isolation: cluster-scoped, governed by the platform. idle cost: clusters bill until terminated, so auto-termination matters. best for: lakehouse-native Spark work.
  • SageMaker Studio — isolation: your AWS account, IAM and VPC boundaries. idle cost: instances bill until stopped. best for: AWS-governed ML teams.
  • Modal — isolation: gVisor user-space kernel. idle cost: structurally low, function-scoped execution. best for: bursty GPU jobs driven from Python.
  • Binder — isolation: containerised, public, ephemeral. idle cost: none, because nothing persists. best for: reproducible public notebooks from a repo.
  • GitHub Codespaces — isolation: per-developer container, repo-defined. idle cost: auto-suspend after inactivity. best for: notebooks that live beside application code.
  • PandaStack (ours) — isolation: a Firecracker microVM with its own guest kernel per user or per request. idle cost: destroy the VM and it is zero; a new one is a ~180ms restore. best for: untrusted or per-student notebooks. no GPUs, no notebook UI.

How to choose, in order

  1. Ask whether any notebook will ever run code you did not write. Students, candidates, customers, external contributors, AI agents — if yes, isolation is your first filter and it removes several options immediately.
  2. Ask whether you need GPUs, and which ones. This is a hard constraint that eliminates candidates faster than anything else, and availability changes constantly, so check today's docs rather than last year's blog post.
  3. Ask where the data already is. A lakehouse, an AWS account with strict egress rules, or an on-premise cluster largely dictates the answer before preferences enter the room.
  4. Ask what your duty cycle looks like. If notebooks are open eight hours and compute for twenty minutes, idle billing will dominate your invoice and scale-to-zero behaviour matters more than the hourly rate.
  5. Ask what must survive a session ending: the file, the installed environment, or the data on disk. Write down which three you need, then check each candidate against that list specifically rather than trusting the word 'persistent'.
  6. Ask whether collaboration is the actual bottleneck. If analysts cannot share work with stakeholders, buy a collaborative notebook product; no amount of infrastructure improvement fixes a presentation problem.
  7. Then prototype the top two for a week with your real notebooks, your real data sizes, and your real users. Every claim in this post, mine included, is a hypothesis until you measure it on your own workload.
One thing worth being blunt about: if you are running a course, a hiring exercise, or a public 'try it in a notebook' demo on a shared-kernel setup, you do not have a security control, you have an honour system. It usually holds, right up until it spectacularly does not, and the incident review will ask what the boundary was. Decide now whether you are comfortable answering 'user accounts on one box'.

The bottom line

There is no best Jupyter hosting platform, only a best fit for six constraints, and the constraints are usually resolved in this order: untrusted code, then GPUs, then data gravity, then idle cost, then persistence, then collaboration. Colab and Binder win the sharing use case outright. Deepnote and Hex win collaboration. Databricks and SageMaker win when the data and the governance already live there. JupyterHub wins when you own the hardware and the operator. Modal wins bursty GPU compute. PandaStack's narrow claim is the isolation axis — a real microVM kernel per user, cheap enough to create per session because a create is a snapshot restore rather than a boot — and it makes no claim at all on GPUs or on being a notebook experience. Pick the axis that is forcing your hand, shortlist two, and spend an afternoon measuring instead of a week reading comparison posts.

Frequently asked questions

What is the best Jupyter notebook hosting platform in 2026?

There is no single winner, because the six deciding axes — kernel isolation, GPU access, idle cost, persistence, collaboration, and untrusted execution — point at different products. Google Colab and Binder are the best options for sharing runnable notebooks with people who have no setup. Deepnote and Hex are the strongest collaborative notebook products for analytics teams. Databricks and SageMaker Studio are the right answers when your data and governance already live in a lakehouse or an AWS account. Self-hosted JupyterHub is correct when you own the hardware and someone to operate it. Decide which axis is forcing your decision first, then shortlist only two candidates and test them against your real notebooks.

Is it safe to run untrusted or student-submitted notebooks?

It depends entirely on what wraps the kernel, and the honest answer for most default setups is no. A Jupyter kernel executes arbitrary code with the privileges of its surrounding process, so a shared-host JupyterHub separated only by user accounts offers very little against a hostile or merely careless notebook — a fork bomb or a memory-exhausting loop takes down everyone. Containerised per-user spawners are a substantial improvement but still share one host kernel. For genuinely untrusted code, the defensible boundary is a virtual machine per user, where each kernel has its own guest kernel and hardware-level isolation. If you are running a course, a hiring exercise, or a public demo, decide which of those three you actually have before the incident rather than after.

How do I stop paying for idle Jupyter notebooks?

First find out what your platform actually bills while nobody is running a cell, because the models differ enormously. Cluster-based platforms like Databricks and instance-based ones like SageMaker Studio bill until something is explicitly terminated or stopped, which makes auto-termination settings the single highest-leverage configuration you will touch. Managed notebook products generally include idle shutdown on some tier, but the timeout length varies and is worth checking. Function-oriented platforms structurally avoid the problem because nothing is held between invocations. And on any platform where creating a fresh kernel is fast, the cheapest idle policy is simply destroying the environment and recreating it — the maths only works if creation is quick enough that users do not resent it.

Do I need GPUs for notebook hosting, and who offers them?

Only if you are training or running models large enough that CPU inference is impractical — a great deal of data analysis, ETL, and visualisation work never needs one, and paying for accelerators you do not use is a common and expensive mistake. If you do need them, GPU availability is the hardest constraint on this list and should be your first filter rather than an afterthought. Colab, Databricks, SageMaker Studio, Modal, and self-hosted JupyterHub on your own cluster all have GPU paths, with very different queueing, cost, and availability characteristics. Specific GPU classes, quotas, and pricing change frequently enough that any figure quoted in a blog post is stale on arrival, so verify against each vendor's current documentation. PandaStack, for the record, has no GPU offering — that is a genuine reason to choose something else.

Can I run JupyterLab inside a microVM sandbox?

Yes, and it is a reasonable architecture when isolation is your binding constraint. The notebook front end and the kernel are separate concerns: you can keep JupyterLab or any other notebook UI, and move only the kernel execution into a per-user virtual machine, so each user's code runs behind a hardware boundary rather than beside their colleagues' processes. On PandaStack that means creating a microVM per user or per session, writing the notebook into it, and executing there — a create is a snapshot restore at 179ms p50, which is what makes per-user VMs affordable rather than theoretical. The trade is that you are assembling a notebook experience rather than buying one, so if collaboration features are what you actually need, a commercial notebook product will serve you better.

Keep reading

Run code in a microVM in one API call.

49ms p50 cold start. Fork, snapshot, and scale to zero.

Start free
Written by Ajay Kumar, Founder, PandaStack.