Docs
Conceptsince 1.0.0-alpha.3

Local mode and cloud mode

penv is in one of two states, decided by the schema header and your credential, and cloud mode keeps an encrypted copy on your machine so runs stay fast.

penv is always in one of two states, and it tells you which one when you type penv with no arguments.

The two states

StateYou are here whenValues come from
Local.env.schema has no @penv= header, or you are not signed in.env on your disk
CloudThe header names a project and you hold a credentialpenv.cloud, through an encrypted local copy

penv push is the move from the first to the second. It sends the values, then deletes .env.

If a .env is still sitting beside a schema that names a cloud project, penv run uses the file and says so on stderr. Delete it once you have pushed, or regenerate it deliberately with penv pull.

What a cloud run actually does

find .env.schema, nearest upward             under 1ms
open the encrypted local copy                about 2ms
  still fresh?  ->  start your program
  ask the server whether anything changed    about 40ms
  changed  ->  fetch, rewrite the local copy
  cannot reach the server  ->  see below

penv aims to start your program in under 50 milliseconds on a warm local copy. The check against the server is a HEAD request carrying the tag from the last fetch (its ETag), so an unchanged environment costs one small round trip and puts no values on the wire.

How long a copy stays fresh

EnvironmentFresh forWhat happens on every run
development60 secondsWithin the window, penv starts your program without asking the server
Every other name0 secondspenv asks the server whether anything changed

The difference is deliberate. You restart a dev server dozens of times an hour and a minute of staleness costs nothing. A production run should not begin on a value someone revoked a minute ago.

Offline

EnvironmentThe server is unreachable
developmentpenv uses the local copy and prints one line saying so, once a day
Every other namepenv refuses with exit code 5

Failing closed on staging and production is the point. Yesterday's copy of a rotated production credential is the wrong answer, so penv would rather stop and tell you than start your program with it.

Where the local copy lives, and what protects it

The copy is a sealed file under your platform's cache directory: %LOCALAPPDATA%\penv\cache on Windows, ~/Library/Caches/penv on macOS, and $XDG_CACHE_HOME/penv or ~/.cache/penv elsewhere.

It is encrypted (ChaCha20-Poly1305) under a 32-byte key that penv keeps in your operating system keychain. The sealed bytes are bound to the server, the environment and the credential that fetched them, so a file for development will not open as production and a file one person fetched will not open for another. A file that will not open reads as no copy at all, so rotating your login is never an error.

A host with no keychain

Containers and most servers have no keychain to hold the key. penv detects that, keeps no local copy at all, and asks the server on every run.

A container running penv run needs the network every time it starts. Build that into your health checks, or use penv pull in the build step for a platform that has to read a file.

What cloud mode buys you

Change it once. It lands everywhere your code runs. A value you set in the console reaches every laptop on its next run, and every pipeline and server the next time one starts. Nobody has to paste anything anywhere.

Next: coding agents.