Your code runs outside API Maker. Custom APIs, hooks, event listeners, schedulers, migrations and test cases run in Docker containers, each language in a sandbox of its own, which every thread of API Maker uses. API Maker hands the request to the sandbox over TCP and gets the answer back.
API Maker is inside the sandbox too. The sandbox holds API Maker itself, as a library of the runner of your language. g.sys.db.query is a function call there: it runs the real API with its checks, and reads the database from the sandbox.
Every run has a time limit. 13 seconds by default. Change it per request with the x-am-sandbox-timeout header, or in the settings of a custom API, a scheduler or a listener.
A stuck sandbox is replaced. It gets no new requests, the ones inside it finish, then it is removed and a new sandbox takes its place. The time to get a sandbox is not counted in the logs.
Your own image, your own packages. Each language of an account gets an image built from its runtime, your packages and your Dockerfile, on every server. Save the settings and the sandboxes start anew from the new image.
Tune it to your load. A runtime and a version per language, the sandbox count of every server or of each one, a separate sandbox for a heavy API, or the native process for code you trust.