Jupyter Notebook Cell Execution Shortcuts
Running code is the whole point of a notebook, and these five shortcuts cover every way of doing it — three variations on running a single cell that differ only in what happens to selection afterward, plus interrupting a stuck cell and restarting the kernel entirely when something has genuinely gone wrong.
| Action | Windows | Mac | Description |
|---|---|---|---|
| Run cell, select next | Shift+Enter | Shift+Return | Executes the current cell's code and moves selection to the next cell (creating a new one if it's the last cell in the notebook), the most commonly used execution shortcut for working through a notebook sequentially. |
| Run cell, insert below | Alt+Enter | Option+Return | Executes the current cell and immediately inserts a new empty cell directly below it, useful when iterating and you know you'll want another cell right after this one regardless of what currently follows. |
| Run cell, stay selected | Ctrl+Enter | Cmd+Return | Executes the current cell but keeps that same cell selected afterward rather than advancing, useful for repeatedly re-running one cell (like a plotting cell) while tweaking its code between runs. |
| Interrupt the running kernel | I, I (Command mode, press twice) | I, I | Stops a currently executing cell mid-run, essential when a cell is stuck in an infinite loop or taking far longer than expected and needs to be halted without restarting the entire kernel and losing all defined variables. |
| Restart the kernel | 0, 0 (Command mode, press zero twice) | 0, 0 | Restarts the Python (or other language) process entirely, clearing all defined variables and requiring every cell to be re-run from scratch — the standard fix for a kernel stuck in a bad state, distinct from Interrupt which only stops the current cell. |
The three "run cell" shortcuts execute identical code with the identical result — the only difference between them is what happens to your selection once execution finishes, and picking the right one for your current task meaningfully speeds up a working session. Shift+Enter runs the current cell and moves selection to the next cell, creating a new empty one automatically if you're on the notebook's last cell — this is the default, most commonly used execution shortcut for working through a notebook sequentially from top to bottom, since it naturally advances you forward without any extra thought.
Alt+Enter (Option+Return on Mac) runs the current cell and always inserts a brand new empty cell directly below it, regardless of whether a cell already existed there — distinct from Shift+Enter, which only creates a new cell if you were already on the last one. Reach for Alt+Enter specifically when you know you want a fresh cell right after this one no matter what, rather than advancing into whatever cell might already exist in that position.
Ctrl+Enter (Cmd+Return on Mac) runs the current cell but keeps that exact same cell selected afterward rather than moving anywhere — the right choice for repeatedly re-running one specific cell while tweaking its code between runs, a genuinely common pattern when iterating on something like a data visualization or a function definition where you want to see the effect of each small change immediately without navigating away and back each time.
Interrupting the kernel (I, I — pressed twice in Command mode, mirroring Delete Cell's double-tap safety pattern) stops whatever cell is currently executing mid-run, without affecting any previously defined variables or completed work — essential when a cell is stuck in an infinite loop, waiting on unresponsive network I/O, or simply taking far longer than you expected and you need to halt it without losing everything else the notebook has already computed.
Restarting the kernel (0, 0 — the zero key pressed twice) is a considerably more drastic action than Interrupt: it terminates the entire underlying Python (or other language) process and starts a fresh one, which means every variable, import, and function definition is wiped clean and every cell needs to be re-run from scratch to rebuild that state. This is the correct fix specifically when the kernel itself is in a genuinely broken state that Interrupt can't reach — memory corruption, a hung low-level extension, or simply a kernel that's become unresponsive to interrupt signals entirely.
Understanding when to reach for which of these two recovery actions matters in practice: Interrupt first, always, since it's non-destructive to your existing session state and often resolves a stuck cell without losing anything. Only escalate to a full Restart if Interrupt genuinely fails to stop the stuck execution, or if you suspect the kernel's internal state has become corrupted in a way a mere interrupt signal can't repair — jumping straight to Restart when Interrupt would have worked costs you the time of re-running every earlier cell to rebuild variables you didn't actually need to lose.
A broader workflow habit worth adopting specifically because of how easy it is for a notebook to develop invisible execution-order dependencies: periodically using the Kernel menu's "Restart & Run All" (mentioned in this page's FAQ) as a genuine sanity check before considering any notebook finished or shareable, since it's the only way to confirm every cell actually works correctly in its written top-to-bottom order rather than only working because of leftover variable state from cells you happened to run out of sequence during exploratory development.