SQL Server Reporting Services: The Complete DBA Guide

SQL Server Reporting Services: The Complete DBA Guide | SQLYARD

SQL Server Reporting Services: The Complete DBA Guide


SQL Server 2016–2022
SSRS Native Mode
SSRS roadmap change: SQL Server 2025. SSRS 2022 is the final version of SQL Server Reporting Services. No new SSRS release ships with SQL Server 2025. Microsoft has consolidated on-premises reporting under Power BI Report Server (PBIRS), which is a superset of SSRS supporting both paginated RDL reports and interactive Power BI reports. SSRS 2022 remains fully supported with security updates until January 11, 2033. This article covers SSRS through SQL Server 2022 and includes a dedicated migration planning section for the PBIRS transition.

SQL Server Reporting Services is the on-premises, server-hosted reporting platform that has delivered paginated, pixel-perfect reports — invoices, regulatory extracts, operational dashboards, and scheduled email deliveries — for over two decades. Tens of thousands of organizations still run SSRS in production today. Understanding the architecture, the ReportServer database internals, subscription management, execution log monitoring, performance diagnosis, and the SQL Server 2025 transition is core DBA knowledge.

1

SSRS Architecture: Components and Databases

Beginner

SSRS runs as a Windows service (SQL Server Reporting Services) separate from the SQL Server Database Engine. The two communicate over HTTP/HTTPS — the report server exposes two URL endpoints configured in Report Server Configuration Manager.

ComponentPurposeDefault URL
Report Server Web ServiceSOAP and REST API endpoint for programmatic access, report deployment, and subscription management/reportserver
Web Portal (Report Manager)Browser-based UI for browsing reports, managing subscriptions, setting permissions, and viewing execution history/reports
ReportServer databaseStores all report definitions, data sources, schedules, subscriptions, execution logs, and security policiesSQL Server database, default name: ReportServer
ReportServerTempDB databaseStores cached report snapshots, temporary session data, and report execution stateSQL Server database, default name: ReportServerTempDB

The Report Server Configuration Manager (not SSMS) handles all SSRS configuration: service account, URL reservations, database connection, email settings, encryption keys, and scale-out deployment. It is a separate tool launched from the Windows Start menu or RSConfigTool.exe.

The SSRS service account needs specific permissions. The SSRS service account must have read and write access to the ReportServer and ReportServerTempDB databases, access to any UNC file share paths used for subscription delivery, and read access to any data sources the reports query. Avoid domain admin rights for the service account — the Report Server Configuration Manager grants exactly the permissions SSRS needs when the account is configured through it.
2

The ReportServer Database: What Is Inside

Intermediate

The ReportServer database is the operational heart of SSRS. Microsoft does not officially support direct modification of its tables, but querying them for monitoring and reporting is standard DBA practice and is widely documented.

Table / ViewContains
dbo.CatalogEvery item in the report server: reports, data sources, folders, resources. The Content column stores the RDL definition as a binary blob.
dbo.ExecutionLogStorageRaw execution log entries. Each row is one report execution event.
dbo.ExecutionLog3View over ExecutionLogStorage with readable column names and time breakdowns. Use this for all monitoring queries.
dbo.SubscriptionsAll subscriptions: delivery method, parameters, owner, last status, last run time.
dbo.ReportScheduleLinks subscriptions to SQL Server Agent job GUIDs. The Agent job name is the subscription’s schedule GUID.
dbo.DataSourceShared data sources and their connection strings (encrypted).
dbo.ConfigurationInfoServer-wide configuration settings: execution log retention days, snapshot limits, email settings.
dbo.UsersUsers and groups with permissions in SSRS.
dbo.PolicyUserRoleSecurity policy assignments: who has what role on which report or folder.
Never modify ReportServer tables directly in production. Querying for monitoring is safe and standard. Writing to the tables outside of the SSRS service — updating subscription parameters, modifying report content, changing configuration — risks corrupting the report server state. Use the SSRS REST API, SSMS web portal, or PowerShell SSRS cmdlets for all writes.
3

Native Mode vs SharePoint Mode

Beginner

SSRS operates in one of two modes set at installation time and not changeable without a reinstall.

ModeDescriptionUse When
Native ModeSSRS manages its own web portal, security model, and URL endpoints. No SharePoint dependency. The most common deployment.Most environments. No SharePoint in the stack, or SharePoint is present but not integrated with SSRS.
SharePoint ModeSSRS integrates as a SharePoint service application. Reports stored in SharePoint document libraries. Security managed through SharePoint.Organizations that have deeply integrated SharePoint with SQL Server BI. SharePoint mode is not available in SQL Server 2022 and later.
SharePoint integrated mode was removed in SQL Server 2019. SQL Server Reporting Services SharePoint integrated mode is not supported on SQL Server 2019 or later. Environments still running SSRS in SharePoint mode must migrate to Native mode before upgrading to SQL Server 2019 or 2022.
4

Data Sources and Datasets

Beginner

Every SSRS report connects to data through a data source. Data sources can be embedded within a report (report-specific) or shared at the server level (reusable across many reports). Shared data sources are the correct choice for any environment with multiple reports connecting to the same database, because a single credential or connection string change propagates to all reports using that shared source.

Data Source TypeStorageCredential Options
Shared data source (.rds)ReportServer database, managed via web portalWindows integrated, stored credentials, no credentials (prompted at runtime)
Embedded data sourceInside the report .rdl fileSame options as shared, but managed per report

Stored credentials in SSRS are encrypted using the symmetric encryption key managed by the Report Server Configuration Manager. The encryption key must be backed up after any significant SSRS configuration change and is required to restore SSRS to a new server. Without the key, stored credentials cannot be decrypted and all subscriptions using stored credentials stop working.

Back up the SSRS encryption key immediately after installation and after any reconfiguration. In Report Server Configuration Manager, go to Encryption Keys, Back Up. Store the backup file and password in a secure location separate from the server. A server rebuild without this key requires manually re-entering all stored credentials and resetting all data-driven subscriptions.
5

Subscriptions: Standard and Data-Driven

Intermediate

Subscriptions deliver reports automatically on a schedule, without user interaction. SSRS supports two types with a meaningful difference in capability and edition requirement.

Subscription TypeEdition RequiredHow It WorksBest For
Standard subscriptionAll editions (Standard, Enterprise)Fixed recipient list, fixed parameters, fixed delivery settings. Configured in the SSRS web portal per report.Sending the same report to the same group of recipients on a schedule
Data-driven subscription (DDS)Enterprise edition onlyRecipients, parameters, and delivery settings are pulled from a SQL query at runtime. Each row in the query generates one delivery.Personalized delivery — each user receives a report filtered to their own data (region, account, sales territory)
Data-driven subscriptions require Enterprise edition. If DDS is missing after a migration to a new server, verify the SQL Server edition. Migrating from Enterprise to Standard removes DDS capability even if the ReportServer database is restored intact. The subscription records still exist in the database but the UI will not expose the data-driven option on Standard edition.

Subscription delivery methods include email (requires SMTP configuration in Report Server Configuration Manager), Windows file share (UNC path, requires credentials with write access to the share), and report server (saves a snapshot to the report server itself). Each delivery method stores configuration in the dbo.Subscriptions table as an XML blob in the ExtensionSettings column.

6

SSRS and SQL Server Agent

Intermediate

Every SSRS subscription schedule creates a SQL Server Agent job in the ReportServer job category. The Agent job name is a GUID that matches the schedule ID in ReportServer.dbo.ReportSchedule. SQL Server Agent must be running for any SSRS subscription to fire. If Agent is stopped, all subscriptions silently stop running without error in the SSRS logs.

-- Find all SSRS subscription Agent jobs with their associated report names
-- Links ReportServer.dbo.ReportSchedule and msdb.dbo.sysjobs
SELECT
    j.name                          AS agent_job_name,
    j.enabled                       AS job_enabled,
    c.Name                          AS report_name,
    c.Path                          AS report_path,
    s.Description                   AS subscription_description,
    s.LastStatus                    AS last_status,
    s.LastRunTime                   AS last_run_time,
    s.DeliveryExtension             AS delivery_method
FROM ReportServer.dbo.ReportSchedule    rs
JOIN ReportServer.dbo.Subscriptions     s  ON rs.SubscriptionID   = s.SubscriptionID
JOIN ReportServer.dbo.Catalog           c  ON s.Report_OID        = c.ItemID
JOIN msdb.dbo.sysjobs                   j  ON j.name = CAST(rs.ScheduleID AS NVARCHAR(128))
ORDER BY s.LastRunTime DESC;
GO
SQL Server Agent job history does not reflect subscription delivery status. An Agent job that fires a subscription can complete successfully (exit code 0) even when the subscription delivery itself fails — for example, when the SMTP server is unavailable or the file share path is wrong. The actual delivery status is in ReportServer.dbo.Subscriptions.LastStatus, not in Agent job history.
7

Permissions Model

Intermediate

SSRS uses its own role-based security model independent of SQL Server database permissions. Roles are assigned to users and groups at the folder or item level through the web portal. SSRS security does not inherit from Windows file system permissions or SQL Server logins.

Built-in RoleCapabilities
BrowserView reports, subscribe to reports, view report history. Standard role for end users.
Content ManagerFull control of content: create, edit, delete reports, manage folders, manage subscriptions for all users. Equivalent to admin for content.
PublisherDeploy reports and data sources to the server. Needed by developers deploying from Visual Studio or Report Builder.
Report BuilderOpen and save reports to the server using Report Builder.
My ReportsManage reports in a personal My Reports folder if the feature is enabled on the server.

System-level roles (applied at the server level rather than a specific folder) include System Administrator (full server management) and System User (view server properties, execute shared schedules).

8

Execution Log: The DBA’s Primary Diagnostic Tool

Intermediate

The execution log records every report execution on the server. It is stored in ReportServer.dbo.ExecutionLogStorage and surfaced through three views: ExecutionLog, ExecutionLog2, and ExecutionLog3. Always use ExecutionLog3 — it is the most recent and contains the most complete set of columns including time breakdowns by processing phase.

By default, log entries are retained for 60 days. The retention period is configurable in the SSRS web portal under Site Settings, or via the ConfigurationInfo table. Entries older than the retention period are deleted at 2:00 AM daily by a cleanup job.

ColumnWhat It MeasuresUnit
TimeDataRetrievalTime spent executing the dataset query against the data sourceMilliseconds
TimeProcessingTime spent processing the report (applying filters, sorting, grouping)Milliseconds
TimeRenderingTime spent rendering the report into the output format (PDF, Excel, HTML)Milliseconds
SourceLive (ran against data source), Cache (snapshot used), Snapshot (from history)String
StatusrsSuccess, or an error code such as rsProcessingAbortedString
RequestTypeInteractive (0), Subscription (1), RefreshCache (2)Integer
-- All executions in the last 24 hours with phase timing
USE ReportServer;
GO

SELECT
    e.UserName,
    e.ItemPath                                      AS report_path,
    e.TimeStart,
    e.TimeEnd,
    DATEDIFF(SECOND, e.TimeStart, e.TimeEnd)        AS total_seconds,
    e.TimeDataRetrieval                             AS data_retrieval_ms,
    e.TimeProcessing                                AS processing_ms,
    e.TimeRendering                                 AS rendering_ms,
    e.Format                                        AS output_format,
    e.Source,
    e.Status,
    CASE e.RequestType
        WHEN 0 THEN 'Interactive'
        WHEN 1 THEN 'Subscription'
        WHEN 2 THEN 'RefreshCache'
        ELSE 'Unknown'
    END                                             AS request_type
FROM dbo.ExecutionLog3 e
WHERE e.TimeStart >= DATEADD(HOUR, -24, GETDATE())
ORDER BY e.TimeStart DESC;
GO
-- Most-run reports in the last 30 days with average execution time
USE ReportServer;
GO

SELECT
    c.Name                                          AS report_name,
    c.Path                                          AS report_path,
    COUNT(*)                                        AS execution_count,
    AVG(DATEDIFF(MILLISECOND, e.TimeStart, e.TimeEnd)) AS avg_duration_ms,
    MAX(DATEDIFF(MILLISECOND, e.TimeStart, e.TimeEnd)) AS max_duration_ms,
    COUNT(DISTINCT e.UserName)                      AS distinct_users,
    SUM(CASE WHEN e.Status <> 'rsSuccess'
             THEN 1 ELSE 0 END)                    AS error_count
FROM dbo.ExecutionLog3 e
JOIN dbo.Catalog       c ON e.ItemPath = c.Path
WHERE e.TimeStart >= DATEADD(DAY, -30, GETDATE())
  AND c.Type = 2   -- 2 = report (excludes folders, data sources)
GROUP BY c.Name, c.Path
ORDER BY execution_count DESC;
GO
9

Diagnosing Slow Reports

Advanced

When a report is slow, the execution log phase timing tells the DBA exactly where time is being spent. Each case points to a different owner and resolution.

Slow PhaseRoot CauseWho Fixes It
High TimeDataRetrievalSlow SQL query on the data source. Missing index, parameter sniffing, blocking, or excessive data being returned.DBA: tune the query, add indexes, check for blocking. Check Query Store on the source database.
High TimeProcessingComplex report logic: many groupings, nested tablix, calculated fields, large datasets loaded into memory.Report developer: simplify report design, pre-aggregate in the query rather than in report expressions.
High TimeRenderingLarge output format (PDF with many pages, Excel with many rows), complex layout, or many embedded images.Report developer: reduce report page count, limit rows exported, simplify layout.
-- Find slowest reports by average data retrieval time (last 14 days)
-- High TimeDataRetrieval = tune the query on the source database
USE ReportServer;
GO

SELECT TOP 20
    c.Name                                          AS report_name,
    COUNT(*)                                        AS execution_count,
    AVG(e.TimeDataRetrieval)                        AS avg_data_retrieval_ms,
    AVG(e.TimeProcessing)                           AS avg_processing_ms,
    AVG(e.TimeRendering)                            AS avg_rendering_ms,
    AVG(DATEDIFF(MILLISECOND, e.TimeStart, e.TimeEnd)) AS avg_total_ms
FROM dbo.ExecutionLog3 e
JOIN dbo.Catalog       c ON e.ItemPath = c.Path
WHERE e.TimeStart >= DATEADD(DAY, -14, GETDATE())
  AND e.Status    = 'rsSuccess'
  AND c.Type      = 2
GROUP BY c.Name
HAVING COUNT(*) >= 5   -- only reports with meaningful sample size
ORDER BY avg_data_retrieval_ms DESC;
GO
-- Reports where rendering is the bottleneck (rendering > 50% of total time)
-- These are report design problems, not database problems
USE ReportServer;
GO

SELECT TOP 20
    c.Name                                          AS report_name,
    COUNT(*)                                        AS execution_count,
    AVG(e.TimeRendering)                            AS avg_rendering_ms,
    AVG(e.TimeDataRetrieval)                        AS avg_data_retrieval_ms,
    AVG(DATEDIFF(MILLISECOND, e.TimeStart, e.TimeEnd)) AS avg_total_ms,
    CAST(AVG(e.TimeRendering) * 100.0 /
         NULLIF(AVG(DATEDIFF(MILLISECOND, e.TimeStart, e.TimeEnd)), 0)
         AS DECIMAL(5,1))                           AS rendering_pct_of_total
FROM dbo.ExecutionLog3 e
JOIN dbo.Catalog       c ON e.ItemPath = c.Path
WHERE e.TimeStart >= DATEADD(DAY, -14, GETDATE())
  AND e.Status    = 'rsSuccess'
  AND c.Type      = 2
GROUP BY c.Name
HAVING COUNT(*) >= 5
   AND AVG(e.TimeRendering) > AVG(e.TimeDataRetrieval)
ORDER BY rendering_pct_of_total DESC;
GO
10

Finding and Alerting on Failed Subscriptions

Intermediate

SSRS subscription failures are silent by default. The Agent job that fires the subscription completes with a success exit code even when delivery fails. The only reliable source of subscription failure status is ReportServer.dbo.Subscriptions.LastStatus. Building a monitoring job that queries this column and alerts on non-success status is the correct approach.

-- Find all subscriptions that failed on their last run
USE ReportServer;
GO

SELECT
    c.Name                          AS report_name,
    c.Path                          AS report_path,
    s.Description                   AS subscription_description,
    s.DeliveryExtension             AS delivery_method,
    s.LastRunTime,
    s.LastStatus,
    s.EventType,
    u.UserName                      AS subscription_owner
FROM dbo.Subscriptions  s
JOIN dbo.Catalog        c ON s.Report_OID = c.ItemID
JOIN dbo.Users          u ON s.OwnerID    = u.UserID
WHERE s.LastStatus NOT LIKE 'Mail sent%'
  AND s.LastStatus NOT LIKE 'New Subscription%'
  AND s.LastStatus <> 'rsSuccess'
  AND s.LastRunTime IS NOT NULL
ORDER BY s.LastRunTime DESC;
GO
-- SQL Server Agent job to alert on failed subscriptions
-- Create this as a daily monitoring job in SQL Server Agent

USE msdb;
GO

-- Step script for the Agent job:
DECLARE @FailedCount INT;
DECLARE @EmailBody   NVARCHAR(MAX);

SELECT @FailedCount = COUNT(*)
FROM ReportServer.dbo.Subscriptions
WHERE LastStatus NOT LIKE 'Mail sent%'
  AND LastStatus NOT LIKE 'New Subscription%'
  AND LastStatus <> 'rsSuccess'
  AND LastRunTime >= DATEADD(DAY, -1, GETDATE());

IF @FailedCount > 0
BEGIN
    SET @EmailBody =
        CAST(@FailedCount AS NVARCHAR(10)) +
        ' SSRS subscription(s) failed in the last 24 hours. ' +
        'Query ReportServer.dbo.Subscriptions for details.';

    EXEC msdb.dbo.sp_send_dbmail
        @profile_name = 'DBA Alerts',
        @recipients   = 'dba-team@yourcompany.com',
        @subject      = 'SSRS Subscription Failures Detected',
        @body         = @EmailBody;
END
GO
11

Identifying Unused Reports

Intermediate

In mature SSRS environments, a significant proportion of deployed reports have not been run in months. Identifying and decommissioning unused reports reduces catalog clutter, simplifies maintenance, and frees up storage. The execution log provides the data; the challenge is that the log only covers the retention window (default 60 days).

-- Reports not run in the last 90 days (within the log retention window)
-- Extend the retention period first if 90 days exceeds the configured retention
USE ReportServer;
GO

SELECT
    c.Name                          AS report_name,
    c.Path                          AS report_path,
    c.CreationDate                  AS created_date,
    c.ModifiedDate                  AS last_modified,
    MAX(e.TimeStart)                AS last_execution,
    COUNT(e.TimeStart)              AS execution_count_in_log
FROM dbo.Catalog                    c
LEFT JOIN dbo.ExecutionLogStorage   e ON e.ReportID = c.ItemID
WHERE c.Type = 2   -- reports only, not folders or data sources
GROUP BY c.Name, c.Path, c.CreationDate, c.ModifiedDate
HAVING MAX(e.TimeStart) < DATEADD(DAY, -90, GETDATE())
    OR MAX(e.TimeStart) IS NULL   -- never run at all
ORDER BY last_execution ASC, c.Name;
GO
-- Increase execution log retention from 60 to 180 days
-- Run this in the ReportServer database (or use Site Settings in the web portal)
USE ReportServer;
GO

UPDATE dbo.ConfigurationInfo
SET Value = '180'
WHERE Name = 'ExecutionLogDaysKept';
GO
-- Note: This takes effect at the next 2:00 AM cleanup run
-- Verify: SELECT Name, Value FROM dbo.ConfigurationInfo WHERE Name = 'ExecutionLogDaysKept'
12

SQL Server 2025: SSRS to Power BI Report Server

Intermediate
SSRS 2022 is the last version. No SSRS ships with SQL Server 2025. Microsoft announced on June 19, 2025 that SQL Server Reporting Services will not receive a new version for SQL Server 2025. SSRS 2022 continues to receive security updates until January 11, 2033. Power BI Report Server (PBIRS) is the replacement, available for SQL Server 2025 Standard and Enterprise edition customers using the same SQL Server 2025 license key.

Power BI Report Server is a superset of SSRS. Everything SSRS does — paginated RDL reports, subscriptions, data sources, security model, ReportServer database — PBIRS also does. PBIRS additionally supports interactive Power BI reports (.pbix files) hosted on-premises. For organizations running only paginated reports, the migration from SSRS to PBIRS is primarily an installation and configuration exercise, not a report rebuild.

AspectSSRS 2022Power BI Report Server (PBIRS)
Paginated RDL reportsFull supportFull support (superset)
Interactive Power BI reports (.pbix)Not supportedSupported
SubscriptionsStandard and DDSStandard and DDS
Security modelSSRS role-basedSame model
ReportServer databaseStandard schemaSame schema (can migrate existing DB)
Update cadenceOptional CUs aligned with SQL ServerQuarterly releases required to stay in support
SQL Server 2025 licensingNot includedIncluded with Standard and Enterprise
SQL Server 2022 licensingIncludedEnterprise with active Software Assurance only
Express editionLimited features availableNot available
In-place upgrade from SSRSN/ANo in-place upgrade path; side-by-side migration required
PBIRS requires quarterly updates to remain in support. Unlike SQL Server CUs which are optional, PBIRS quarterly releases must be applied to maintain Microsoft support. Organizations accustomed to a “install and leave” patching approach for SSRS need to build PBIRS quarterly patching into their operational calendar.
13

Migration Checklist: SSRS to PBIRS

Advanced

There is no in-place upgrade from SSRS to PBIRS. The migration involves installing PBIRS on a new server, migrating the ReportServer database, transferring the encryption key, and validating every component before cutover. Run SSRS and PBIRS in parallel until validation is complete.

StepActionNotes
1Inventory all reports, data sources, and subscriptionsQuery dbo.Catalog and dbo.Subscriptions for a complete list. Count standard subscriptions and DDS separately.
2Document all URL reservationsRecord /reports and /reportserver paths, port numbers, and any TLS certificates attached. These must be reconfigured on PBIRS.
3Back up the SSRS encryption keyReport Server Configuration Manager, Encryption Keys, Back Up. This key decrypts stored credentials — without it, all credentials must be re-entered manually.
4Document custom extensionsCustom authentication, rendering, delivery, or data processing extensions are version-sensitive and must be rebuilt or tested against PBIRS before cutover.
5Install PBIRS on the target serverUse the SQL Server 2025 license key. PBIRS installs separately from the SQL Server Database Engine.
6Restore or attach the ReportServer databaseRestore from backup to the PBIRS server’s SQL Server instance. PBIRS can use the existing ReportServer database schema.
7Import the encryption key into PBIRSReport Server Configuration Manager on the PBIRS server, Encryption Keys, Restore. Use the backup file from Step 3.
8Configure URL reservations and TLSRe-create the same URL reservations in PBIRS Configuration Manager. Attach TLS certificates if HTTPS was in use.
9Validate subscriptionsRun each subscription type (email, file share) manually using Run Now. Verify delivery and check dbo.Subscriptions.LastStatus.
10Validate custom extensionsTest every custom extension. These are the most common silent failure point after migration.
11Update DNS or load balancerPoint the report server hostname to the PBIRS server. End users should reach PBIRS at the same URL they used for SSRS.
12Decommission SSRS after a validation periodRun SSRS and PBIRS in parallel for at least two subscription cycles before decommissioning the old server.
-- Pre-migration inventory: full report and subscription count
-- Run on the existing SSRS ReportServer database before migration
USE ReportServer;
GO

SELECT
    'Reports'           AS item_type,
    COUNT(*)            AS total_count
FROM dbo.Catalog WHERE Type = 2
UNION ALL
SELECT 'Data Sources', COUNT(*) FROM dbo.Catalog WHERE Type = 5
UNION ALL
SELECT 'Standard Subscriptions',
       COUNT(*) FROM dbo.Subscriptions WHERE DataSettings IS NULL
UNION ALL
SELECT 'Data-Driven Subscriptions',
       COUNT(*) FROM dbo.Subscriptions WHERE DataSettings IS NOT NULL
UNION ALL
SELECT 'Shared Schedules',
       COUNT(*) FROM dbo.Schedule
UNION ALL
SELECT 'Users with permissions',
       COUNT(DISTINCT UserID) FROM dbo.Users;
GO

The technical information in this article was verified against Microsoft documentation at the time of publication. SQL Server features, cloud service capabilities, licensing terms, and configuration requirements can change between versions and cumulative updates. Always validate implementation details against current Microsoft Learn documentation before deploying to production. References in this article link directly to the authoritative Microsoft sources.

References


Discover more from SQLYARD

Subscribe to get the latest posts sent to your email.

Leave a Reply

Discover more from SQLYARD

Subscribe now to keep reading and get access to the full archive.

Continue reading