QuestDB JavaScript Client - v5.0.0
    Preparing search index...

    Module @questdb/nodejs-client

    The QuestDB JavaScript client.

    This entry point targets Node.js. Use @questdb/browser-client for the browser build.

    QuestDB JavaScript Client for Node.js

    The official QuestDB client for Node.js and TypeScript. Use it to ingest rows with the InfluxDB Line Protocol (ILP), ingest and query with the QuestDB Wire Protocol (QWP), and keep publishing through outages with Node-only persistent store-and-forward.

    The complete Node.js API is exported from @questdb/nodejs-client. There are no additional public import paths.

    • ILP ingestion over HTTP, HTTPS, TCP, and TLS-encrypted TCP
    • QWP ingestion over WebSocket, secure WebSocket, and UDP
    • Streaming QWP queries with typed bind variables and result batches
    • Automatic batching, failover, reconnect, and acknowledgement tracking
    • Persistent QWP store-and-forward for process and server outages
    • ESM, CommonJS, and bundled TypeScript declarations
    • Node.js 20.18.1 or newer (the floor undici declares; an earlier v20 warns with EBADENGINE and fails outright under engine-strict)
    • A running QuestDB instance
    • QWP endpoints /write/v4 and /read/v1 for QWP ingestion and queries
    npm install @questdb/nodejs-client
    
    yarn add @questdb/nodejs-client
    
    pnpm add @questdb/nodejs-client
    

    Sender buffers rows locally. Add as many complete rows as needed, then call flush() to send the batch.

    import { Sender } from "@questdb/nodejs-client";

    const sender = await Sender.fromConfig("http::addr=localhost:9000");

    try {
    await sender
    .table("trades")
    .symbol("symbol", "ETH-USD")
    .symbol("side", "buy")
    .floatColumn("price", 2_615.54)
    .floatColumn("amount", 0.25)
    .at(Date.now(), "ms");

    await sender.flush();
    } finally {
    await sender.close();
    }

    HTTP and HTTPS connect for each request. TCP, TCPS, WS, WSS, and UDP transports have an explicit connection, so call await sender.connect() before writing.

    Configuration prefix Protocol Typical use
    http::, https:: ILP Recommended general-purpose ingestion
    tcp::, tcps:: ILP Long-lived ILP connection
    ws::, wss:: QWP Acknowledged ingestion, failover, and store-and-forward
    udp:: QWP Fire-and-forget datagrams on trusted networks

    Use encrypted transports and certificate verification outside trusted local development environments.

    Avoid flushing after every row when the application can send a larger batch. The sender also supports automatic flushing through its configuration options.

    import { Sender } from "@questdb/nodejs-client";

    const sender = await Sender.fromConfig("http::addr=localhost:9000");

    try {
    for (const trade of [
    { symbol: "ETH-USD", price: 2_615.54, amount: 0.25 },
    { symbol: "BTC-USD", price: 59_750.1, amount: 0.01 },
    ]) {
    await sender
    .table("trades")
    .symbol("symbol", trade.symbol)
    .floatColumn("price", trade.price)
    .floatColumn("amount", trade.amount)
    .atNow();
    }

    await sender.flush();
    } finally {
    await sender.close();
    }

    Passing null or undefined to a supported symbol or column method omits that column from the row, which records a SQL NULL in QuestDB.

    Configuration strings use the form protocol::key=value;key=value. HTTP Basic authentication uses username and password; REST and OIDC access tokens use token.

    import { Sender } from "@questdb/nodejs-client";

    const sender = await Sender.fromConfig(
    `https::addr=questdb.example:9000;token=${process.env.QUESTDB_TOKEN};tls_verify=on`,
    );

    try {
    await sender.table("service_health").booleanColumn("healthy", true).atNow();
    await sender.flush();
    } finally {
    await sender.close();
    }

    The same configuration can be provided through QDB_CLIENT_CONF:

    import { Sender } from "@questdb/nodejs-client";

    // QDB_CLIENT_CONF=http::addr=localhost:9000
    const sender = await Sender.fromEnv();

    Changing the configuration prefix to ws:: or wss:: selects QWP while keeping the familiar Sender row API.

    import { Sender } from "@questdb/nodejs-client";

    const sender = await Sender.fromConfig(
    `wss::addr=questdb.example:9000;token=${process.env.QUESTDB_TOKEN};auto_flush=off`,
    );
    await sender.connect();

    try {
    await sender
    .table("trades")
    .symbol("symbol", "ETH-USD")
    .floatColumn("price", 2_615.54)
    .timestampColumn("received_at", Date.now(), "ms")
    .atNow();

    await sender.flush();
    } finally {
    await sender.close();
    }

    QWP senders support server acknowledgements, durable acknowledgements, transactions, reconnect, failover, compiled row writers, and metrics. See the QWP guide for the delivery semantics of each option.

    For repeated object-shaped rows, compile a table schema once. TypeScript then checks each row against that schema.

    import {
    Sender,
    designatedTimestamp,
    double,
    long,
    symbol,
    } from "@questdb/nodejs-client";

    const sender = await Sender.fromConfig("ws::addr=localhost:9000");
    await sender.connect();

    try {
    const trades = sender.writer("trades", {
    symbol: symbol(),
    side: symbol(),
    price: double(),
    quantity: long(),
    timestamp: designatedTimestamp("ns"),
    });

    await trades.rows([
    {
    symbol: "ETH-USD",
    side: "buy",
    price: 2_615.54,
    quantity: 42n,
    timestamp: 1_723_000_000_000_000_000n,
    },
    {
    symbol: "BTC-USD",
    side: "sell",
    price: 59_750.1,
    quantity: 1n,
    timestamp: 1_723_000_001_000_000_000n,
    },
    ]);

    await sender.flush();
    } finally {
    await sender.close();
    }

    Compiled writers are available with QWP transports only.

    QWP egress streams typed result batches. One egress session executes one active query at a time.

    import { connectQwpNodeEgress } from "@questdb/nodejs-client";

    const session = await connectQwpNodeEgress(
    {
    url: "wss://questdb.example:9000/read/v1",
    authorization: `Bearer ${process.env.QUESTDB_TOKEN}`,
    compression: "zstd",
    },
    { queryTimeoutMs: 30_000 },
    );

    try {
    const query = await session.query(
    "select timestamp, symbol, price from trades where symbol = $1",
    {
    // Bind index 0 corresponds to SQL placeholder $1.
    binds: (binds) => binds.setVarchar(0, "ETH-USD"),
    initialCredit: 1024 * 1024,
    },
    );

    for await (const batch of query) {
    for (const row of batch.rows()) {
    console.log(row);
    }
    }

    await query.completion;
    } finally {
    await session.close();
    }

    Use queryViews() instead of query() for reusable, allocation-conscious column and row views.

    Node.js can journal QWP frames to disk before sending them. The producer can continue accepting rows during a QuestDB outage and replay them in order after reconnection.

    import { Sender } from "@questdb/nodejs-client";

    const sender = await Sender.fromConfig(
    "wss::" +
    "addr=questdb-a.example:9000,questdb-b.example:9000;" +
    "sf_dir=/var/lib/my-service/questdb-replay;" +
    "initial_connect_retry=async;",
    );

    await sender.connect();

    Give every active producer its own journal directory. Durability, backpressure, capacity, orphan recovery, and shutdown behavior are covered in the store-and-forward section of the QWP guide.

    • Always call close() in a finally block.
    • Call flush() before closing an ILP sender; otherwise buffered rows are lost.
    • A QWP sender publishes completed rows during close, but an unfinished row is never completed implicitly.
    • Do not write concurrently through one Sender. Give each worker or producer its own sender.
    • Treat authentication and protocol errors as configuration failures rather than retrying the same request indefinitely.

    Classes

    HttpTransport
    QwpBatchTooLargeError
    QwpBindValues
    QwpByteReader
    QwpByteWriter
    QwpClient
    QwpClientClosedError
    QwpDurableAckUnavailableError
    QwpEgressQuery
    QwpEgressQueryAbandonedError
    QwpEgressQueryCancelTimeoutError
    QwpEgressQueryError
    QwpEgressQueryTimeoutError
    QwpEgressReplayRequiredError
    QwpEgressSession
    QwpEgressSessionClosedError
    QwpFailoverError
    QwpIngressAckAbandonedError
    QwpIngressAckTimeoutError
    QwpIngressNackError
    QwpIngressSession
    QwpIngressSessionClosedError
    QwpMemoryReplayAppendTimeoutError
    QwpMemoryReplayBatchTooLargeError
    QwpMemoryReplayFrameTooLargeError
    QwpNodeFileReplayStore
    QwpNodeOrphanDrainer
    QwpNodeUdpSession
    QwpPoolAcquireTimeoutError
    QwpPoolResourceError
    QwpProtocolError
    QwpQueryLease
    QwpReconnectExhaustedError
    QwpReplayDictionaryError
    QwpReplayDictionaryPersistenceError
    QwpReplayRejectedError
    QwpReplayStoreAppendTimeoutError
    QwpReplayStoreBatchTooLargeError
    QwpReplayStoreCheckpointError
    QwpReplayStoreCorruptionError
    QwpReplayStoreError
    QwpReplayStoreFullError
    QwpReplayStoreLockedError
    QwpReplayStoreLockLostError
    QwpReplayStoreLockUnprovableError
    QwpReplayStoreQuarantinedError
    QwpReplayStoreSegmentTooLargeError
    QwpResultBatch
    QwpResultBatchDecoder
    QwpResultBatchView
    QwpResultColumnView
    QwpResultRowView
    QwpRoleMismatchError
    QwpSendClosedError
    QwpSender
    QwpSenderCloseTimeoutError
    QwpSendError
    QwpSendTimeoutError
    QwpSymbolDictionary
    QwpTableBuffer
    QwpTableWriter
    QwpUdpDatagramTooLargeError
    QwpUnrecoverableReplayDictionaryError
    QwpUpgradeError
    QwpVersionMismatchError
    QwpWriterRowError
    Sender
    SenderBufferV1
    SenderBufferV2
    SenderBufferV3
    SenderOptions
    TcpTransport
    UndiciTransport

    Interfaces

    QwpArrayValue
    QwpBinaryConnection
    QwpCacheResetMessage
    QwpClientFactories
    QwpClientMetrics
    QwpClientPoolOptions
    QwpColumnBuffer
    QwpConnectionCloseInfo
    QwpDecimalValue
    QwpEgressMetrics
    QwpEgressQueryOptions
    QwpEgressReplayResetEvent
    QwpEgressRoutingOptions
    QwpEgressSessionOptions
    QwpEgressTransportMetrics
    QwpEgressViewQuery
    QwpEncodedBinds
    QwpExecDoneMessage
    QwpFailoverAttempt
    QwpFrame
    QwpFrameHeader
    QwpGeohashValue
    QwpHandshakeMetadata
    QwpIngressEncodeOptions
    QwpIngressErrorEvent
    QwpIngressMetrics
    QwpIngressProgressEvent
    QwpIngressReplayRecord
    QwpIngressReplayReference
    QwpIngressReplayStore
    QwpIngressResponse
    QwpIngressSendResult
    QwpIngressServerInfo
    QwpIngressSessionOptions
    QwpIngressSymbolDictionaryDelta
    QwpIngressTableResult
    QwpIngressTransportMetrics
    QwpLong256Value
    QwpNodeClientConfigOptions
    QwpNodeClientOptions
    QwpNodeEgressOptions
    QwpNodeFileReplayStoreMetrics
    QwpNodeFileReplayStoreOptions
    QwpNodeIngressOptions
    QwpNodeOrphanDrainerMetrics
    QwpNodeOrphanDrainerOptions
    QwpNodeOrphanDrainEvent
    QwpNodeOrphanDrainSession
    QwpNodeReplayDataLossReport
    QwpNodeReplayRecoveryEvent
    QwpNodeStoreAndForwardOptions
    QwpNodeUdpMetrics
    QwpNodeUdpOptions
    QwpNodeUdpSocketLike
    QwpNodeUpgradeRejection
    QwpNodeWebSocketOptions
    QwpPoolSlotReservation
    QwpQueryErrorMessage
    QwpQueryRequest
    QwpReconnectEvent
    QwpReconnectOptions
    QwpResourcePoolMetrics
    QwpResultArrayValue
    QwpResultBatchMessage
    QwpResultColumn
    QwpResultColumnSchema
    QwpResultEndMessage
    QwpSenderEncodeOptions
    QwpSenderError
    QwpSenderErrorResponseContext
    QwpSenderMetrics
    QwpSenderOptions
    QwpSenderSession
    QwpServerInfoMessage
    QwpSymbolValue
    QwpUpgradeErrorDetails
    QwpUuidValue
    QwpWebSocketConnectOptions
    QwpWebSocketLike
    QwpWriterColumn
    SenderBuffer
    SenderTransport

    Type Aliases

    ExtraOptions
    Logger
    QwpBindSetter
    QwpBindType
    QwpColumnType
    QwpConnectionFactory
    QwpDecimalInput
    QwpDoubleArrayInput
    QwpEgressCompression
    QwpEgressMessage
    QwpEgressViewCallbackControl
    QwpExtraOptions
    QwpGeohashInput
    QwpIngressProgressKind
    QwpInitialConnectMode
    QwpInt64
    QwpIpv4Input
    QwpLong256Input
    QwpLong256Words
    QwpLongArrayInput
    QwpNegotiatedEgressCompression
    QwpNestedLongArray
    QwpNestedNumberArray
    QwpNodeOrphanDrainEventKind
    QwpQueryCompletion
    QwpReconnectEventKind
    QwpResultBatchViewHandler
    QwpResultRowViewCallback
    QwpResultValue
    QwpSenderErrorCategory
    QwpSenderErrorPolicy
    QwpSenderLogger
    QwpSenderSessionFactory
    QwpSfBackpressurePolicy
    QwpSfDurability
    QwpTarget
    QwpTimestampUnit
    QwpUpgradeErrorKind
    QwpUpgradeTimeoutPhase
    QwpUuidInput
    QwpWriterColumnKind
    QwpWriterRow
    QwpWriterSchema
    TimestampUnit

    Variables

    QWP_COLUMN_TYPE
    QWP_COMPRESSION_CODEC
    QWP_DECIMAL_MAX_SCALE
    QWP_DEFAULT_EGRESS_BUFFER_POOL_SIZE
    QWP_DEFAULT_EGRESS_INITIAL_CREDIT
    QWP_DEFAULT_EGRESS_SERVER_INFO_TIMEOUT_MS
    QWP_DURABLE_ACK_WEBSOCKET_PROTOCOL
    QWP_EGRESS_CAPABILITY
    QWP_EGRESS_MESSAGE
    QWP_EGRESS_PATH
    QWP_ENCODING_GORILLA
    QWP_ENCODING_UNCOMPRESSED
    QWP_FLAG_DEFER_COMMIT
    QWP_FLAG_DELTA_SYMBOL_DICTIONARY
    QWP_FLAG_DURABLE_ACK_POLL
    QWP_FLAG_GORILLA
    QWP_FLAG_ZSTD
    QWP_HEADER_SIZE
    QWP_INGRESS_PATH
    QWP_INGRESS_PROGRESS_KIND
    QWP_INGRESS_SERVER_INFO_CAPABILITY
    QWP_INITIAL_CONNECT_MODE
    QWP_MAGIC
    QWP_MAX_ARRAY_DIMENSION_LENGTH
    QWP_MAX_ARRAY_DIMENSIONS
    QWP_MAX_BATCH_ROWS_UPPER_BOUND
    QWP_MAX_CELLS_PER_BATCH
    QWP_MAX_COLUMN_NAME_LENGTH
    QWP_MAX_COLUMNS_PER_TABLE
    QWP_MAX_IDENTIFIER_BYTES
    QWP_MAX_ROWS_PER_TABLE
    QWP_MAX_SYMBOL_DICTIONARY_SIZE
    QWP_MAX_TABLE_NAME_LENGTH
    QWP_MAX_TABLES_PER_FRAME
    QWP_MAX_ZSTD_DECOMPRESSED_SIZE
    QWP_ORPHAN_DRAIN_EVENT_KIND
    QWP_ORPHAN_FAILED_SENTINEL
    QWP_QUERY_FLAG_RESET_DICTIONARY
    QWP_RECONNECT_EVENT_KIND
    QWP_RESET_MASK_DICTIONARY
    QWP_SENDER_ERROR_CATEGORY
    QWP_SENDER_ERROR_POLICY
    QWP_SERVER_ROLE
    QWP_SF_BACKPRESSURE_POLICY
    QWP_SF_DURABILITY
    QWP_STATUS
    QWP_TARGET
    QWP_UPGRADE_ERROR_KIND
    QWP_UPGRADE_TIMEOUT_PHASE
    QWP_VERSION
    QWP_ZSTD_MAX_COMPRESSION_LEVEL
    QWP_ZSTD_MIN_COMPRESSION_LEVEL

    Functions

    addQwpDurableAckWebSocketProtocol
    bigintToTwosComplementBytes
    binary
    bool
    byte
    char
    concatBytes
    connectQwpNodeClient
    connectQwpNodeEgress
    connectQwpNodeIngress
    connectQwpNodeSender
    connectQwpNodeUdp
    connectQwpNodeUdpSender
    connectQwpNodeWebSocket
    createBuffer
    createQwpDataLossSenderError
    createQwpNodeClient
    createQwpNodeConnectionFactory
    createQwpNodeSender
    createQwpNodeUdpSender
    createQwpProtocolViolationSenderError
    createQwpSenderError
    createTransport
    date
    decimal128
    decimal256
    decimal64
    decodeQwpContentEncoding
    decodeQwpEgressMessage
    decodeQwpFrame
    decodeQwpIngressResponse
    decodeQwpIngressServerInfo
    decodeQwpIngressSymbolDictionaryDelta
    decodeQwpVarint
    decodeUtf8
    decompressQwpZstdFrame
    defaultQwpSenderErrorHandler
    designatedTimestamp
    double
    doubleArray
    encodeQwpAcceptEncoding
    encodeQwpBinds
    encodeQwpCancel
    encodeQwpCredit
    encodeQwpDurableAckPollFrame
    encodeQwpFrame
    encodeQwpGorilla
    encodeQwpIngressCommitFrame
    encodeQwpIngressFrame
    encodeQwpIngressSymbolDictionaryFrame
    encodeQwpQueryRequest
    encodeQwpVarint
    encodeUtf8
    flattenQwpArray
    float32
    float64
    geohash
    int32
    int64
    ipv4
    isQwpDurableAckWebSocketProtocol
    long
    long256
    longArray
    parseQwpNodeClientConfig
    qwpDefaultSenderErrorPolicy
    qwpGorillaSize
    qwpSenderErrorCategory
    qwpVarintSize
    readQwpVarint
    readQwpVarintNumber
    retryQwpNodeOrphanSlot
    scanQwpNodeOrphanSlots
    short
    symbol
    timestamp
    utf8Length
    uuid
    varchar
    writeQwpFrameHeader
    writeQwpVarint