amphetamine 0.1.1

Reclaim memory and win scheduler contention on Apple Silicon, safely.
amphetamine-0.1.1 is not a library.

Amphetamine: A Memory and Contention Tool for Apple Silicon

Amphetamine frees memory and reduces CPU contention on macOS, so your editor gets the machine's attention.

It closes only the apps you have named, clears only caches that belong to installed applications, and refuses to make any change it cannot undo.

Contents

Scope

Amphetamine can free memory and reduce contention; it cannot make your cores run faster. Being straight about that matters more than the pitch.

Clock Speed

There is no overclocking. Apple Silicon exposes no user-space clock control — no cpufreq, no multiplier, nothing, SIP enabled or not.

The only performance selector is the Energy Mode in System Settings, and amph status will tell you if you are not already on High Power. If nothing is thermally throttling you, there is no clock speed to win back, and any tool claiming otherwise is lying.

Available Levers

What is real is contention and memory pressure.

  • Closing apps — a quit request, as if you pressed Cmd-Q, frees RAM and, critically, drains swap.
  • Clearing caches — age-gated file deletion frees disk and reduces cache-warming I/O.
  • Deprioritisingnice gives rival processes a weaker claim on the CPU.
  • Idle-sleep hold — an IOKit power assertion keeps long builds from being interrupted.

Swap

Swap is usually the real culprit. Free RAM is a poor health signal; swap is a better one.

Pages pushed to swap during past pressure stay there, and every touch of one is a disk read. Swap only drains as the processes owning those pages exit — no amount of free RAM, and no purge, brings it back.

That is why closing apps helps even on a 128 GB machine.

Efficiency Cores

nice is not efficiency-core parking. PRIO_DARWIN_PROCESS, the mechanism behind taskpolicy -b, silently does nothing when aimed at another process on current macOS: it reports success and changes no state.

Amphetamine uses nice, which measurably works, and does not claim to do more.

Installation

Amphetamine requires macOS on Apple Silicon and a recent stable Rust. The package is named amphetamine and the command it installs is amph.

Install it from crates.io.

cargo install amphetamine

Build from source instead if you want to run the tests or track main.

cargo build --release
cp target/release/amph /usr/local/bin/

Usage

Every command is listed here, and amph with no argument is the read-only status view.

amph                     # same as `amph status`
amph status              # read-only: memory, swap, thermal, heaviest apps
amph pick                # choose what to close, interactively
amph boost --dry-run     # exactly what would be closed and cleared
amph boost               # do it
amph focus --for 90      # a 90-minute focus session
amph restore             # undo any leftover deprioritisation

The first run writes ~/.config/amphetamine/config.toml with empty lists and changes nothing. That is the design, not an oversight: Amphetamine closes an app only after you name it.

Configuration

You never have to open the config by hand.

amph pick                # tick apps from what's running, ranked by memory
amph add Slack Spotify   # or name them directly
amph add -d Dropbox      # -d: deprioritise during focus instead
amph add -p Notion       # -p: protect, never close
amph rm Spotify          # remove from a list
amph config show         # every setting, annotated with what's running

amph pick opens a checklist of running apps pre-ticked to match your current config, so it reads as an editor rather than a one-way import. Apps that are protected are never offered, and entries for apps that aren't running are left untouched rather than silently dropped.

Names match a bundle ID, an app name, or the last component of a bundle ID, case-insensitively. They are stored using the app's own spelling, so amph add slack records Slack.

Adding something the built-in denylist protects is refused with the reason rather than accepted as a line that could never fire.

$ amph add Cursor Docker
close list
  ! Cursor not added — protected (Cursor) — it would never be touched
  ! Docker not added — protected (Docker) — it would never be touched

Edits are made in place with toml_edit, so the config's explanatory comments survive. Each result is parsed back and validated before it replaces the file, and the swap is atomic, so a failed edit leaves the previous config whole.

For hand-editing, amph config edit opens $EDITOR and amph config raw prints the file as-is.

A filled-in config is short.

[apps]
close = ["Slack", "Spotify", "Messages"]

[caches]
min_age_days = 7

[focus]
demote = ["Spotify", "Dropbox"]
nice_level = 10

Permissions

Closing apps, clearing your caches, and reading every statistic here need no privileges at all, and there is no daemon.

Focus mode needs exactly one grant, because of a macOS asymmetry: any user may raise a process's nice value, but only root may lower it again. Without help, deprioritising an app would be a one-way door — so Amphetamine refuses to demote anything until it can prove it can undo it.

amph setup asks for your password once and installs a single sudoers rule.

you ALL=(root) NOPASSWD: /usr/bin/renice 0 -p [0-9]*

The 0 is literal. The rule can only ever return a process to normal priority: it cannot deprioritise anything, cannot run any other command, and cannot open a shell.

It is validated with visudo -c before installation, because a malformed file in /etc/sudoers.d can lock you out of sudo entirely.

Inspect it with amph setup --print, remove it with amph setup --remove.

Safety Model

Amphetamine is built so that the dangerous operations are the ones it refuses to perform.

The Denylist

A hard-coded denylist that config cannot override covers three groups: the OS and your session (WindowServer, Finder, Dock, loginwindow), your work surface (Cursor, every common terminal), and everything holding mutable state (all VMs, Docker, Parallels, UTM). All of them are refused even if you name them explicitly.

Killing a VM abruptly can corrupt its disk image, so Amphetamine reports those and stops.

Quit Requests

Apps are asked, never killed. Closing goes through NSRunningApplication::terminate, the same quit request as Cmd-Q, so the app runs its normal shutdown and is free to put up an unsaved-work sheet.

If it does not exit within the timeout it is simply left running — a stalled app is usually one asking you to save something.

SIGKILL is never sent; --force exists and is never implied.

Cache Eligibility

Caches must prove they are caches. ~/Library/Caches is not one kind of thing: alongside app caches it holds compiler and package-manager state that is ruinously expensive to rebuild.

On the machine this was developed against, go-build alone was 91 GB and a dead-code analyser's cache was 39 GB.

So the rule is a positive test rather than a denylist that could never keep pace: a bucket is eligible only if an application with that bundle identifier is actually installed, per LaunchServices. Everything unrecognised is left alone, which makes tools you install next year safe by default.

Four more brakes apply on top of that test.

  • Live state — buckets holding it (CloudKit, container manager) are permanently excluded.
  • Developer tools — IDEs and browsers are skipped by default.
  • Running apps — a cache whose app is currently running is never touched, including its .ShipIt updater.
  • Age — only files untouched, by both modification and access time, for min_age_days are eligible.

Deletion Scope

Deletion is narrow by construction. Only ~/Library/Caches and ~/Library/Logs, never configurable.

Symlinks are never followed, and a symlinked bucket is skipped whole. Every path is re-canonicalised and re-vetted against its root immediately before removal, so nothing can escape through a link swapped in mid-run.

There is no recursive delete anywhere: files are removed individually and directories only via remove_dir, which fails unless already empty.

Reversibility

Nothing is irreversible. Focus mode verifies its restore path before touching a process, only demotes processes already at nice 0 (so restoring to 0 is exact rather than a guess), and restores on exit.

If a session is killed outright, amph restore is the safety net.

Tests

The suite asserts refusals more than successes.

Run it against your own machine.

cargo test

53 tests, run against the live machine rather than mocks.

The ones that matter check that the built-in denylist beats an explicit close request, that a symlink cannot lead a delete outside its root, that build-tool caches are never touched, and that nothing is demoted without a proven way back.

One is a canary: lowering a nice value without privileges still fails. If it ever passes, the sudoers grant is no longer needed.

The Other Amphetamine

If you came here for the macOS menu-bar utility that keeps your Mac awake, that is a different and unrelated program.

This tool holds off idle sleep only for the length of a focus session, and it is not a keep-awake utility. The two share a name and nothing else.

There are two other reasons to leave. No tool can give you overclocking on Apple Silicon, and Amphetamine is built on Mach, libproc, AppKit and IOKit, so it refuses to compile anywhere but macOS.

Bug Reports

Bugs and feature requests belong in the issue tracker.

Security problems do not. Amphetamine installs a sudoers rule and deletes files, so a flaw in either could matter to people other than you; report those through a private security advisory instead of a public issue.