Serverless functions are a black box, and New Relic Lambda Monitoring lets you peek inside.

Imagine a single HTTP request hitting your API Gateway. It triggers a Lambda function, which then calls a DynamoDB table, which then invokes another Lambda function, which finally writes to an S3 bucket. Without proper monitoring, if that request fails or takes ages, you have no idea where the bottleneck or failure occurred. Was it the initial Lambda? The DynamoDB latency? The second Lambda? The S3 write? New Relic Lambda Monitoring stitches all these disparate, ephemeral pieces together into a single, coherent trace.

Here’s a look at a trace in action. Let’s say you have a user_signup Lambda.

{
  "traceId": "abc123xyz789",
  "parentId": null,
  "id": "def456uvw012",
  "name": "user_signup",
  "timestamp": "2023-10-27T10:00:00.000Z",
  "duration": 1500,
  "kind": "SERVER",
  "localRootSpanId": "def456uvw012",
  "serviceName": "user-service",
  "resourceAttributes": {
    "faas.name": "user_signup",
    "faas.runtime": "nodejs18.x",
    "cloud.provider": "aws",
    "faas.trigger": "http",
    "faas.execution": "a1b2c3d4e5f60123456789abcdef"
  },
  "events": [
    {
      "name": "log",
      "timestamp": "2023-10-27T10:00:00.500Z",
      "attributes": {
        "message": "Starting user validation"
      }
    },
    {
      "name": "db.query",
      "timestamp": "2023-10-27T10:00:01.200Z",
      "duration": 400,
      "attributes": {
        "db.system": "dynamodb",
        "db.statement": "GET user_id = 'testuser'",
        "aws.operation": "GetItem"
      }
    },
    {
      "name": "log",
      "timestamp": "2023-10-27T10:00:01.600Z",
      "attributes": {
        "message": "User validated, proceeding to create profile."
      }
    }
  ]
}

This snippet shows a single span representing the user_signup Lambda. It has a traceId (abc123xyz789) that links it to other spans in the same request. The parentId would point to the upstream service (e.g., API Gateway). Crucially, it includes resourceAttributes that tell us it’s a serverless function (faas.name, faas.runtime, cloud.provider) triggered by HTTP (faas.trigger), and even the specific execution ID (faas.execution). The events array contains crucial details: a log message, and a db.query event with attributes detailing the database system, the query, and the AWS operation. If this Lambda had called another Lambda, you’d see a child span with faas.trigger: "lambda" and faas.name of the downstream function.

New Relic Lambda Monitoring works by deploying a Lambda Layer to your functions. This layer injects an agent that automatically instruments your code. For supported runtimes (Node.js, Python, Java, Go, .NET, Ruby), the agent automatically captures a wealth of information without requiring code changes. It hooks into the Lambda runtime’s execution environment, starting a trace when your function is invoked and ending it when it returns.

The core problem this solves is distributed tracing for ephemeral, event-driven architectures. In a traditional monolith, tracing is relatively straightforward. In serverless, components spin up and down rapidly, and communication often happens asynchronously via queues or event buses. New Relic Lambda Monitoring bridges these gaps by:

  • Automatic Instrumentation: The Lambda Layer handles the heavy lifting, capturing invocation details, execution time, memory usage, and cold start indicators.
  • Cross-Service Tracing: It automatically correlates Lambda invocations with upstream services (like API Gateway, SQS, SNS) and downstream services (like DynamoDB, S3, other Lambdas). This is achieved through context propagation, where trace headers are passed from one service to the next.
  • Error Tracking: Errors thrown within your Lambda functions are captured and associated with the relevant trace, showing you exactly when and where the failure occurred.
  • Performance Metrics: Beyond just traces, it provides aggregated metrics on invocation counts, error rates, duration percentiles, and cold start frequencies, allowing you to identify performance trends.

The exact levers you control are primarily in the New Relic configuration. You’ll set up an NR_ACCOUNT_ID and NR_LICENSE_KEY (or NR_API_KEY) environment variables on your Lambda functions. The Lambda Layer itself is versioned, and you select the appropriate version in your Lambda function’s configuration. You can also configure the layer to send data to specific regions or filter certain types of events. For more advanced scenarios, you can manually instrument specific code paths using the New Relic SDKs, though the automatic instrumentation covers a vast majority of common use cases.

What most people don’t realize is that the faas.trigger attribute isn’t just for show; it’s a critical piece of how New Relic reconstructs the request flow. When a Lambda is triggered by an event source like API Gateway, the event payload often contains headers or metadata that the New Relic agent can parse to identify the upstream traceId. This is how a trace can start at API Gateway, pass through your Lambda, and then continue to another Lambda or service, all linked together seamlessly. If this context is lost or malformed, your trace will start or end prematurely.

The next step after getting basic Lambda monitoring set up is often integrating it with your other AWS services, like API Gateway, to achieve end-to-end tracing of your serverless applications.

Want structured learning?

Take the full Newrelic course →