How to Fetch Large Volumes of Entra Sign-In Events

Heavy Volume of Sign-in Events in Microsoft 365 Tenants Makes Retrieval Challenging

Every time a user, app, service principal, or agent authenticates against Entra ID, the action generates a sign-in log. These records are an invaluable source of information about who or what accessed a tenant, when the access occurred, and how authentication was performed. Understanding how to retrieve sign-in logs efficiently is an important skill for Microsoft 365 administrators, especially when investigating security incidents, troubleshooting access problems, or analyzing tenant activity.

Entra ID stores sign-in logs online for varying periods depending on licensing and the type of event. Tenants with Microsoft Entra ID P1 or P2 licenses can access sign-in logs for the previous 30 days through the Graph API or the Get-MgAuditLogSignIn cmdlet. Risky sign-ins have different retention periods.

Entra ID sign-in events can also be captured in the Microsoft 365 unified audit log when audit logging is enabled. The unified audit log has different retention rules and stores audit data for 180 days for Office 365 E3 accounts and 365 days for Office 365 E5 and higher licenses, meaning that sign-in audit data is available for much longer through Microsoft 365, where it can be accessed through the Search-UnifiedAuditLog cmdlet or the AuditLogQuery Graph API (Azure Automation is a great way to run Graph-based audit log searches involving large amounts of data).

The Problem with Sign-In Logs

The problem with sign-in logs is that they are typically among the largest datasets in a tenant. A busy Microsoft 365 tenant can generate millions of sign-in events over the 30-day rolling window during which the events are available for online. Even though Graph paginates the results, retrieving all events for a wide date range requires many backend queries and continuation requests. The Entra admin center attempts to avoid problems by using a 7-day period as its default range and paging in additional logs as required (Figure 1).

Entra admin center displays sign-in logs.
Figure 1: Entra admin center displays sign-in logs

The net result is that it’s all too easy to encounter a situation where retrieval of sign-in data results in the error:

The request was canceled due to the configured HttpClient. Timeout of 300 seconds elapsing.

Microsoft explicitly warns that the Graph API is not intended for bulk retrieval of activity data, saying “The Microsoft Graph API isn’t designed for pulling large amounts of activity data. Pulling large amounts of activity data using the API might lead to issues with pagination and performance.” Later in the same page, Microsoft says, “Consider using a date filter so the request doesn’t time out.”

Throttling can also be an issue. All Graph workloads impose some form of throttling to ensure that they can service requests predictably. Entra ID is no different, and it is easy to provoke throttling when retrieving large volumes of sign-in data.

Danger Signals

When writing PowerShell to fetch Entra ID sign-in data, the following are some of the reasons why problems might be encountered:

  • The tenant generates high volumes of sign-in events because it supports a large number of users.
  • The script uses a broad date range or doesn’t filter against the createdDateTime property.
  • The script attempts to retrieve all available pages by passing the -All parameter.
  • Graph throttling causes retries and delays when cmdlets run.

The Solution is to Split Work Up

The obvious solution is to divide the retrieval workload into multiple smaller requests and combine the results afterward. Smaller queries are much less likely to encounter timeout or throttling issues than a single request that attempts to retrieve a large volume of data.

This is exactly what tenants do when they wish to store audit data (from Entra ID or the unified audit log) for extended periods by moving it into an independent repository like Sentinel or Splunk. Data is often fetched daily and ingested into the target repository, where the data can be queried for however long the tenant chooses to retain it in the repository.

I’ve used the divide and conquer technique in different ways within Microsoft 365, notably to retrieve message trace data to check for inactive distribution lists. Message trace data is also voluminous, and the Get-MessageTraceV2 cmdlet only supports retrieval in chunks of no more than 10 days. By splitting the 90-day period into smaller segments, it’s possible to fetch all the message data for the entire period.

Applying the technique to Entra ID sign-in records could mean fetching data in 30 one-day chunks, or, for very large tenants, 720 one-hour chunks. To demonstrate the technique, I coded up a script which you can download from the Microsoft 365 for IT Pros GitHub repository.

The script demonstrates the principle rather than delivering a production-ready solution. Depending on the volume of sign-in data generated by your tenant, you might need to adjust chunk sizes or add additional error handling. However, the underlying technique is simple: divide large retrieval jobs into smaller units that Graph can process efficiently. After all, people have been dividing to conquer for a very long time.

JSON batching is another technique worth considering for fetching large amounts of data from Graph endpoints. Setting up the batch requests, handling retries and pagination, and reconciling the output from multiple requests is obviously more complex than executing a series of PowerShell cmdlets. However, JSON batching is very powerful and worthwhile. I’ll return to this topic soon.


Support the work of the Microsoft 365 for IT Pros team by subscribing to the Microsoft 365 for IT Pros eBook. Your support pays for the time we need to track, analyze, and document the changing world of Microsoft 365 and Office 365. Only humans contribute to our work!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.