Node SDK

Use RudderStack’s Node SDK to send server-side events to various destinations.

RudderStack’s Node SDK lets you track and send the events from your Node applications to the specified destinations.

See the Node SDK GitHub codebase for implementation-specific details.

Github Badge

SDK setup requirements

  1. Sign up for RudderStack Cloud.
  2. Set up a Node source in the dashboard. You should be able to see the write key for this source:
Node source write key

You will also need the data plane URL. Refer to the Dashboard Overview guide for more information on the data plane URL and where to find it.

warning
Make sure to enclose the write key and data plane URL parameters within double quotes (" ").
success
The Setup tab in the RudderStack dashboard (seen above) has the SDK installation snippet containing both the write key and the data plane URL. Copy it to integrate the Node SDK into your application.

Installing the Node SDK

To install the RudderStack Node SDK using npm, run the following command:

npm install @rudderstack/rudder-sdk-node

Initializing the SDK

Run the following snippet to initialize the Node SDK. It creates a global RudderStack client object that can be used for all subsequent event requests.

SDK initialization options

The RudderStack Node SDK provides the following parameters which you can pass during the SDK initialization:

ParameterData typeDescription
flushAtIntegerNumber of events flushed by the SDK when reached this limit.

Default value: 20
flushIntervalIntegerMaximum timespan (in milliseconds) after which the events from the in-memory queue are flushed.

Default value: 10000
maxInternalQueueSizeIntegerMaximum length of the in-memory queue.

Default value: 20000
logLevelStringSets the logging level. The acceptable values are info, debug, error, etc.

Default value: info

The following initialization parameters are only available for RudderStack Node SDK v2.x.x and above:

ParameterData typeDescription
dataPlaneUrlStringData plane URL.

Default value: https://hosted.rudderlabs.com
pathStringPath to the batch endpoint.

Default value: /v1/batch
maxQueueSizeIntegerMaximum payload size of a batch request.

Default value: 460800 (500KB)
axiosConfigObjectAxios configuration.
axiosInstanceObjectAxios instance.
axiosRetryConfigObjectAxios retry configuration.
retryCountIntegerNumber of times a request is retried by Axios in case of failure.

Default value: 3
errorHandlerFunctionFunction that is called if the request to server fails.
gzipBooleanGzip compresses the event request.

Default value: true
warning
For gzipping requests, your rudder-server must be on v1.4.0 or above. Otherwise, your requests will fail.

Sending events

warning
RudderStack does not store or persist the user state in any of the server-side SDKs.

Unlike the client-side SDKs that deal with a single user at a given time, the server-side SDKs deal with multiple users simultaneously. Therefore, you must specify either the userId or anonymousId every time while making any API calls supported by the Node SDK.

Identify

The identify call lets you identify a visiting user and associate them to their actions. It also lets you record the traits about them like their name, email address, etc.

A sample identify call is as shown:

client.identify({
  userId: "1hKOmRA4GRlm",
  traits: {
    name: "Alex Keener",
    email: "alex@example.com",
    plan: "Free",
    friends: 21,
  },
})

The identify parameters are as described below:

FieldTypeDescription
userId
Required, if anonymousId is absent.
StringUnique identifier for a user in your database.
anonymousId
Required, if userId is absent.
StringUse this field to set an identifier in cases where there is no unique user identifier.
contextObjectAn optional dictionary of information that provides context about a message. It is not directly related to the API call.
integrationsObjectAn optional dictionary containing the destinations to be either enabled or disabled.
timestampDateThe timestamp of the message’s arrival.
traitsObjectDictionary of the user’s traits like name or email.

Track

The track call lets you track the user actions along with any properties associated with them.

A sample track call is shown below:

client.track({
  userId: "1hKOmRA4GRlm",
  event: "Item Viewed",
  properties: {
    revenue: 19.95,
    shippingMethod: "Premium",
  },
})

The track method parameters are as described below:

FieldTypeDescription
userId
Required, if anonymousId is absent.
StringUnique identifier for a user in your database.
anonymousId
Required, if userId is absent.
StringUse this field to set an identifier in cases where there is no unique user identifier.
event
Required
StringName of the event.
propertiesObjectAn optional dictionary of the properties associated with the event.
contextObjectAn optional dictionary of information that provides context about a message. It is not directly related to the API call.
timestampDateThe timestamp of the message’s arrival.
integrationsObjectAn optional dictionary containing the destinations to be either enabled or disabled.

Page

The page call allows you to record the page views on your application, along with the other relevant information about the page.

A sample page call is as shown:

client.page({
  userId: "1hKOmRA4GRlm",
  category: "Food",
  name: "Pizza",
  properties: {
    url: "https://example.com",
    title: "Pizza",
    referrer: "https://google.com",
  },
})

The page method parameters are as described below:

FieldTypeDescription
userId
Required, if anonymousId is absent.
StringUnique identifier for a user in your database.
anonymousId
Required, if userId is absent.
StringUse this field to set an identifier in cases where there is no unique user identifier.
name
Required
StringName of the viewed page.
contextObjectAn optional dictionary of information that provides context about a message. It is not directly related to the API call.
timestampDateThe timestamp of the message’s arrival.
integrationsObjectAn optional dictionary containing the destinations to be either enabled or disabled.
propertiesObjectAn optional dictionary of the properties associated with the viewed page, like url and referrer.

Screen

The screen call is the mobile equivalent of the page call. It lets you record the screen views on your mobile app along with other relevant information about the screen.

A sample screen call is as shown:

client.screen({
  userId: "12345",
  category: "Food",
  name: "Pizza",
  properties: {
    screenSize: 10,
    title: "Pizza",
    referrer: "https://google.com",
  },
})

The screen method parameters are as described below:

FieldTypeDescription
userId
Required, if anonymousId is absent.
StringUnique identifier for a user in your database.
anonymousId
Required, if userId is absent.
StringUse this field to set an identifier in cases where there is no unique user identifier.
name
Required
StringName of the viewed page.
contextObjectAn optional dictionary of information that provides context about a message. It is not directly related to the API call.
timestampDateThe timestamp of the message’s arrival.
integrationsObjectAn optional dictionary containing the destinations to be either enabled or disabled.
propertiesObjectAn optional dictionary of the properties associated with the screen, like url or referrer.

Group

The group call lets you link an identified user with a group, such as a company, organization, or an account. It also lets you record any custom traits or properties associated with that group.

A sample group call is as shown:

client.group({
  userId: "12345",
  groupId: "1",
  traits: {
    name: "Company",
    description: "Google",
  },
})

The group method parameters are as follows:

FieldTypeDescription
userId
Required, if anonymousId is absent.
StringUnique identifier for a user in your database.
anonymousId
Required, if userId is absent.
StringUse this field to set an identifier in cases where there is no unique user identifier.
groupId
Required
StringUnique identifier for the group present in your database.
contextObjectAn optional dictionary of information that provides context about a message. It is not directly related to the API call.
integrationsObjectAn optional dictionary containing the destinations to be either enabled or disabled.
traitsObjectAn optional dictionary of the group’s traits like nameor email.
timestampDateThe timestamp of the message’s arrival.

Alias

The alias call lets you merge different identities of a known user. It is an advanced method that lets you change the tracked user’s ID explicitly. You can use alias for managing the user’s identity in some of the downstream destinations.

warning
RudderStack supports sending alias events only to select downstream destinations. Refer to the destination-specific documentation for more details.

A sample alias call is as shown:

client.alias({
  previousId: "old_id",
  userId: "new_id",
})

The alias method parameters are as mentioned below:

FieldTypeDescription
userId
Required
StringUnique identifier for a user in your database.
anonymousIdStringUse this field to set an identifier in cases where there is no unique user identifier.
previousId
Required
StringThe previous unique identifier of the user.
contextObjectAn optional dictionary of information that provides context about a message. It is not directly related to the API call.
integrationsObjectAn optional dictionary containing the destinations to be either enabled or disabled.
traitsObjectAn optional dictionary of the user’s traits like name or email.
timestampDateThe timestamp of the message’s arrival.

Data persistence

warning
This is a beta feature. Contact the RudderStack team on Slack if you face any issues.

If the Node SDK fails to deliver the events to RudderStack in the first attempt, it retries the event delivery. However, if RudderStack is unavailable for a longer duration, there is a possibility of data loss. To prevent this scenario, the SDK has the data persistence feature where the event data is persisted in Redis, guaranteeing event delivery. Simultaneously, the SDK can retry multiple times as the queue is maintained in a different process space (Redis).

info
To use this feature, you will need to host a Redis server to use it as the intermediary data storage queue. RudderStack uses Bull as the interface layer between the Node SDK and Redis.

To achieve data persistence, you need to call the createPersistenceQueue method which takes two parameters - queueOpts and callback. It initializes the persistent queue. A sample SDK initialization is shown below:

warning
If the createPersistenceQueue method is not called after initializing the SDK, the SDK will work without any persistence.

queueOpts

The syntax for createPersistenceQueue method is as follows:

client.createPersistenceQueue(QueueOpts, callback)

A sample queueOpts initialization is shown below:

queueOpts {
  queueName ?: string = rudderEventsQueue,
  isMultiProcessor ?: boolean = false
  // pass a value without the {}, this will used as prefix to Redis keys,
  // needed to support Redis cluster slots.
  prefix?: string = {rudder},
  redisOpts : RedisOpts,
  jobOpts?: JobOpts
}

The specification of the different queueOpts parameters is listed in the following table:

ParameterDescriptionDefault Value
queueNameName of the queue.20
isMultiProcessorDetermines whether to handle previously active jobs. If set to false, the previously active job will be picked up first by the processor. Otherwise, Bull moves this job to the back of the Redis queue to be picked up after the already pushed event.false
prefixUsed as the prefix to the Redis keys needed to support the Redis cluster slots.20000
redisOptsRefer to the RedisOpts section below.RedisOpts
jobOptsRefer to the JobOpts section below.JobOpts

For more information on these parameters, refer to the Bull docs.

warning
If the same queue (RudderStack SDK initialized with the same queue name) is used in case of multiple servers (server-side SDKs), set the value of isMultiProcessor to true as event ordering is not applicable in this case.

RedisOpts

RedisOpts {
  port?: number = 6379;
  host?: string = localhost;
  db?: number = 0;
  password?: string;
}

JobOpts

JobOpts {
  maxAttempts?: number = 10
}

callback

In case of an error, the createPersistenceQueue method returns a callback. You should retry sending the events in this scenario.

// createPersistenceQueue calls this with error or nothing(in case of success), // user should retry in case of error
callback: function(error) || function()

Calling the createPersistenceQueue method initializes a Redis list by calling the Bull’s utility methods. It also adds a single job processor for the processing (making requests to RudderStack) jobs that are pushed into the list. Any error encountered while doing this leads to a callback with the error.

info
If the callback returns with an error, RudderStack recommends retry calling createPersistenceQueue with a backoff.

Event flow

  • Calling the SDK methods like track, page, identify, etc. pushes the events to an in-memory array.
  • The events from the array are flushed as a batch to the Redis persistence based on the flushAt and flushInterval settings. The in-memory array has a maximum size of maxInternalQueueSize. Once this size limit is reached, __the events won’t be accepted if not drained to the other side (cases where Redis connection is slow or the Redis server is not reachable).
  • The processor will take the batch from the Redis list and make a request to RudderStack. In case of an error, the processor will retry sending the data again if the error can be retried (errors with status code 5xx and 429). The retry will go up to JobOpts.maxAttempts with an exponential backoff of power 2 with max backoff of 30 seconds.
  • If the job fails even after JobOpts.maxAttempts, it will not be retried again and pushed to a failed queue. You can retry them later manually using Bull’s utility methods listed here or get them from Redis directly.
  • There might be a scenario where the node process dies with the jobs still in active state (not completed nor failed but in the process of sending/retrying). Since the RudderStack SDK has only 1 processor for sending events (this count should always be 1), the next time the SDK is initialized and createPersistenceQueue is called, the jobs will be picked up first by the processor to get processed to maintain event ordering based on the value of QueueOpts.isMultiProcessor.
  • For multiple servers (SDK) connecting to the same queue (QueueOpts.queueName), there will be multiple processors fetching events from the same queue and event ordering won’t be implemented. Hence, QueueOpts.isMultiProcessor should be set to true.

FAQ

How to ensure that all my events in the queue are processed?

You can use the flush() method to ensure that all events in the queue are processed. The following example highlights the use of flush() with a callback:

client.flush(function(err, batch){
  console.log('Flushing done');
})

How does the Node SDK handle events larger than 32KB?

The Node SDK accepts and sends each event greater than 32KB as a single batch and sends them to the backend.

Does the Node SDK support event ordering?

The Node SDK does not support event ordering by default.



Questions? Contact us by email or on Slack