# node:process

The `node:process` module provides `process`, the Node.js object that holds information about the current process and controls its execution. In a function, its frequent uses are reading environment variables through `process.env` and scheduling work with `process.nextTick()`. Deployed, `process.env` holds the environment variables of your account, which you can also read with `Azion.env.get()`.

In Azion Runtime, `process` is also a global, but the global and the default export of `node:process` are different objects. In the examples below, the global `process.env.NODE_ENV` returns `production`, and the same property of the imported object returns no value.

> **Note**
>
> Under `azion dev`, the `nextTick` callbacks of the deferred execution example run before `End`, and the response lists both of them. Without a `.env` file in the project, `process.env` holds the whole shell environment of the machine that runs `azion dev`.

---

## Examples

Each example is a complete function that imports from `node:process`. The response below each example is the one a deployed function returns.

### Environment variables and nextTick

This function logs the global `process.env.NODE_ENV`, schedules a callback with `nextTick`, and returns the value in the response:

```javascript
/**
 * An example of using the Node.js Process API in an Azion Function.
 * Support:
 *  - Extended by library `process`
 *    Portions of this file Copyright Roman Shtylman, licensed under the MIT license.
 * @module runtime-apis/nodejs/process/main
 * @example
 * // Build and run with the Azion CLI:
 * azion build
 * azion dev
 */
import { env, nextTick } from "node:process";

/**
 * Example of using the process api
 * @param {*} event
 */
const main = async (event) => {
  console.log(process.env.NODE_ENV);

  nextTick(() => {
    console.log("Hello, Next Tick!");
    // Deployed, this line was not logged before the response was sent
  });

  return new Response(`NODE_ENV: ${process.env.NODE_ENV}`, { status: 200 });
};

export default main;
```

The function logs `production` and responds with this body:

```text
NODE_ENV: production
```

### Configuration from environment variables

This function reads four configuration values from `process.env`, falls back to a default for each one, and reports whether an API key is set without exposing its value:

```javascript
import process from "node:process";

const main = async (event) => {
  // Read environment variables
  const nodeEnv = process.env.NODE_ENV || "development";
  const apiKey = process.env.API_KEY;
  const debug = process.env.DEBUG === "true";
  const maxRetries = parseInt(process.env.MAX_RETRIES || "3", 10);

  console.log("Environment:", nodeEnv);
  console.log("Debug mode:", debug);
  console.log("Max retries:", maxRetries);

  // Check if required variables are set
  if (!apiKey) {
    console.warn("API_KEY not configured");
  }

  // Build configuration object
  // Security: Never expose sensitive env vars in responses
  // Use boolean flags instead of actual values
  const config = {
    environment: nodeEnv,
    debug,
    maxRetries,
    hasApiKey: !!apiKey  // Boolean only, not the actual key
  };

  return new Response(JSON.stringify(config), {
    headers: { "Content-Type": "application/json" }
  });
};

export default main;
```

With none of the four variables set, the function logs the warning `API_KEY not configured` and responds with the defaults:

```json
{"environment":"development","debug":false,"maxRetries":3,"hasApiKey":false}
```

### Deferred execution with nextTick

This function records the order in which its code runs around two `nextTick` calls, waits 10 ms, and returns the order:

```javascript
import { nextTick } from "node:process";
import { setTimeout } from "node:timers/promises";

const main = async (event) => {
  const executionOrder = [];

  executionOrder.push("Start");

  // Schedule with nextTick - runs after the current code
  // Deployed, the callbacks have not run when the response is built
  nextTick(() => {
    executionOrder.push("NextTick callback");
    console.log("Deferred execution completed");
  });

  executionOrder.push("After nextTick call");

  // Schedule a second callback
  nextTick(() => {
    executionOrder.push("Second nextTick");
  });

  // Wait 10 ms before building the response
  await setTimeout(10);

  executionOrder.push("End");

  console.log("Execution order:", executionOrder.join(" -> "));

  return new Response(JSON.stringify({ executionOrder }), {
    headers: { "Content-Type": "application/json" }
  });
};

export default main;
```

In a deployed function, the `nextTick` callbacks have not run when the function builds its response, so the order ends at `End` and lists neither callback:

```json
{"executionOrder":["Start","After nextTick call","End"]}
```

### Process information

This function reads the platform, architecture, versions, and process IDs, and returns them as formatted JSON:

```javascript
import process from "node:process";

const main = async (event) => {
  // In Azion Runtime, these process properties return fixed values:
  // - process.platform and process.arch are empty strings
  // - process.pid is 200 and process.ppid is 100
  // - process.versions holds only the node field

  // Platform information
  const platform = process.platform;
  const arch = process.arch;
  const versions = process.versions;

  // Process identification
  const pid = process.pid;
  const ppid = process.ppid;

  // Runtime information
  const nodeVersion = process.version;
  const v8Version = versions.v8;

  console.log("Platform:", platform);
  console.log("Architecture:", arch);
  console.log("Node version:", nodeVersion);
  console.log("V8 version:", v8Version);
  console.log("Process ID:", pid);

  // Build info object with fallbacks for potentially undefined values
  const processInfo = {
    platform,
    arch,
    pid,
    ppid,
    nodeVersion,
    v8Version,
    versions: {
      node: versions.node || "unknown",
      v8: versions.v8 || "unknown",
      openssl: versions.openssl || "unknown"
    }
  };

  return new Response(JSON.stringify(processInfo, null, 2), {
    headers: { "Content-Type": "application/json" }
  });
};

export default main;
```

The function responds with the fixed values. `v8Version` is undefined, so `JSON.stringify` leaves it out of the body:

```json
{
  "platform": "",
  "arch": "",
  "pid": 200,
  "ppid": 100,
  "nodeVersion": "v22.14.0",
  "versions": {
    "node": "22.14.0",
    "v8": "unknown",
    "openssl": "unknown"
  }
}
```

### Memory usage

This function reads `process.memoryUsage()` before and after it builds an array, and returns both readings and the difference:

```javascript
import process from "node:process";

const main = async (event) => {
  // Get initial memory usage
  const initialMemory = process.memoryUsage();

  // Simulate some work
  const data = [];
  for (let i = 0; i < 1000; i++) {
    data.push({ id: i, data: "x".repeat(100) });
  }

  // Get memory usage after work
  const finalMemory = process.memoryUsage();

  // Calculate memory delta
  const memoryDelta = {
    rss: finalMemory.rss - initialMemory.rss,
    heapTotal: finalMemory.heapTotal - initialMemory.heapTotal,
    heapUsed: finalMemory.heapUsed - initialMemory.heapUsed,
    external: finalMemory.external - initialMemory.external
  };

  console.log("Initial heap used:", initialMemory.heapUsed, "bytes");
  console.log("Final heap used:", finalMemory.heapUsed, "bytes");
  console.log("Memory delta:", memoryDelta.heapUsed, "bytes");

  return new Response(JSON.stringify({
    initial: {
      rss: initialMemory.rss,
      heapTotal: initialMemory.heapTotal,
      heapUsed: initialMemory.heapUsed
    },
    final: {
      rss: finalMemory.rss,
      heapTotal: finalMemory.heapTotal,
      heapUsed: finalMemory.heapUsed
    },
    delta: memoryDelta
  }), {
    headers: { "Content-Type": "application/json" }
  });
};

export default main;
```

Every field of `process.memoryUsage()` returns `0`, so both readings and the difference are `0`:

```json
{"initial":{"rss":0,"heapTotal":0,"heapUsed":0},"final":{"rss":0,"heapTotal":0,"heapUsed":0},"delta":{"rss":0,"heapTotal":0,"heapUsed":0,"external":0}}
```

### Uptime and timing

This function reads `process.uptime()` and `process.hrtime()`, then measures a 100 ms wait with `process.hrtime.bigint()`:

```javascript
import process from "node:process";
import { setTimeout } from "node:timers/promises";

const main = async (event) => {
  // Get process uptime in seconds
  const uptime = process.uptime();

  // Get high-resolution time
  const hrtime = process.hrtime();
  const hrtimeBigint = process.hrtime.bigint();

  console.log("Process uptime:", uptime, "seconds");
  console.log("High-res time:", hrtime);
  console.log("High-res time (bigint):", hrtimeBigint.toString(), "nanoseconds");

  // Measure an operation; deployed, the measured time is 0
  const start = process.hrtime.bigint();

  // Simulate work
  await setTimeout(100);

  const end = process.hrtime.bigint();
  const elapsedNs = Number(end - start);
  const elapsedMs = elapsedNs / 1_000_000;

  console.log("Operation took:", elapsedMs.toFixed(2), "ms");

  return new Response(JSON.stringify({
    uptime: {
      seconds: uptime,
      formatted: formatUptime(uptime)
    },
    hrtime: {
      seconds: hrtime[0],
      nanoseconds: hrtime[1]
    },
    operationTime: {
      nanoseconds: elapsedNs,
      milliseconds: elapsedMs
    }
  }), {
    headers: { "Content-Type": "application/json" }
  });
};

// Helper function defined before export
function formatUptime(seconds) {
  const hours = Math.floor(seconds / 3600);
  const minutes = Math.floor((seconds % 3600) / 60);
  const secs = Math.floor(seconds % 60);
  return `${hours}h ${minutes}m ${secs}s`;
}

export default main;
```

Deployed, `process.uptime()` returns `0`, `process.hrtime()` returns whole seconds with `0` nanoseconds, and the time measured across the 100 ms wait is `0`:

```json
{"uptime":{"seconds":0,"formatted":"0h 0m 0s"},"hrtime":{"seconds":1767268800,"nanoseconds":0},"operationTime":{"nanoseconds":0,"milliseconds":0}}
```

---

## Supported APIs

The table lists the status of each `node:process` API in Azion Runtime:

| API                       | Status                                |
| ------------------------- | ------------------------------------- |
| `process.env`             | 🟢 Supported                          |
| `process.nextTick()`      | 🟢 Supported                          |
| `process.platform`        | 🟡 Partially supported (empty string) |
| `process.arch`            | 🟡 Partially supported (empty string) |
| `process.version`         | 🟢 Supported                          |
| `process.versions`        | 🟡 Partially supported (`node` only)  |
| `process.pid`             | 🟡 Partially supported (fixed value)  |
| `process.ppid`            | 🟡 Partially supported (fixed value)  |
| `process.uptime()`        | 🟡 Partially supported (returns `0`)  |
| `process.hrtime()`        | 🟡 Partially supported                |
| `process.hrtime.bigint()` | 🟡 Partially supported                |
| `process.memoryUsage()`   | 🟡 Partially supported (returns `0`)  |
| `process.cwd()`           | 🟡 Partially supported                |
| `process.exit()`          | 🟡 Partially supported                |
| `process.on()`            | 🟡 Partially supported                |
| `process.argv`            | 🟡 Partially supported                |
| `process.title`           | 🟡 Partially supported                |
| `process.binding()`       | 🔴 Not supported                      |

APIs marked 🟡 Partially supported have limited functionality compared to the full Node.js implementation. Their values are fixed and do not describe the machine that runs your code. `process.platform`, `process.arch`, and `process.title` are empty strings, `process.pid` is `200`, and `process.ppid` is `100`. `process.version` is `v22.14.0`, and `process.versions` holds only `node`. `process.cwd()` returns `/`, and `process.argv` is an empty array. Deployed, `process.hrtime()` and `process.hrtime.bigint()` return whole seconds with `0` nanoseconds.

`process.exit()` does not terminate the runtime process, and `process.on()` has limited event support. `process.binding()` throws `Error: [unenv] process.binding is not implemented yet!`. For environment configuration, use `process.env`, which is fully supported.

---

## Related resources

- [Node.js APIs](/en/documentation/devtools/runtime/node.md): The status of every Node.js module in Azion Runtime, `process` included.
- [Environment variables API](/en/documentation/devtools/runtime/api-reference/environment-variables.md): How a function reads the environment variables of your account with `Azion.env.get()`.
- [node:os](/en/documentation/devtools/runtime/node/os.md): The os module, whose functions also return fixed values inside a function.
- [Node.js process documentation](https://nodejs.org/api/process.html): The full Node.js reference for every `node:process` API in the table.
