Out of the box, Windows Server 2025 balances power savings and compatibility rather than maximum speed, which means CPU throttling, generic drivers, and always-on background services can quietly cap performance. This guide walks through a repeatable tuning process: first establish a baseline with Task Manager, Performance Monitor, and Get-Counter so you know which resource is actually constrained, then apply targeted changes in order. You will switch the power plan to High Performance, adjust processor scheduling, disable non-essential services, optimize storage for the correct media type, replace generic drivers with vendor drivers, tune network throughput, and finally stand up monitoring so the gains stick.
Several steps change system behavior and require reboots, so back up your configuration and test changes during a maintenance window. Always verify a setting (media type before defragmenting, switch support before enabling Jumbo Frames, workload type before changing scheduling) rather than applying it blindly.
Before you start
What you will learn
- You will learn how to baseline and tune Windows Server 2025 across six areas-power and processor scheduling, memory and services, storage, drivers and firmware, networking, and ongoing monitoring-using built-in tools and PowerShell.
- Windows Server ships with defaults that favor energy efficiency and broad compatibility over raw throughput, so production servers often leave measurable performance on the table. Tuning these settings reduces latency, frees RAM, and helps hardware run at its rated speeds.
Requirements
- You need local administrative rights on the target Windows Server 2025 host (an elevated PowerShell/Command Prompt session), plus the ability to schedule and complete at least one reboot in a maintenance window. Vendor driver/firmware updates require download access to your OEM's support site or update tool.
- Local Administrator on the target server
- Hyper-V Administrator (only if applying SR-IOV/VMQ virtual switch settings in Step 6)
Good to know
- Plan for 1-2 hours plus at least one reboot; monitoring runs on an ongoing schedule.
- Steps use built-in Windows Server 2025 tools and PowerShell; some commands (Hyper-V VMQ/SR-IOV, SQL layout) apply only to those roles.
Quick answer
Baseline the server first, then tune in order: set the High Performance power plan, disable unneeded services to free RAM, optimize storage for the media type, install vendor drivers, tune networking, and set up monitoring. Reboot where required and verify each change. Back up first-several steps are non-reversible without effort.
powercfg /setactive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635cStep-by-step tutorial
7 stepsIdentify performance bottlenecks with built-in tools
Establish a baseline and pinpoint which resource is constrained before changing anything.
Task Manager > Performance | Performance Monitor (perfmon) > Monitoring Tools > Performance MonitorStart by measuring real utilization so later changes can be judged against a baseline rather than guesswork.
- Open Task Manager with elevated privileges from an elevated PowerShell session:
2. Go to the Performance tab and review CPU, Memory, Disk, and Network. Flag any resource sustaining usage above 80%. 3. Launch Performance Monitor by running perfmon and add these counters: - \Processor(_Total)\% Processor Time - \Memory\Available MBytes - \PhysicalDisk(_Total)\% Disk Time - \Network Interface(*)\Bytes Total/sec 4. For a quick scripted snapshot, run the Get-Counter sample in the command block below.
Get-Counter "\Processor(_Total)\% Processor Time","\Memory\Available MBytes","\PhysicalDisk(_Total)\% Disk Time" -SampleInterval 5 -MaxSamples 12Run monitoring during peak usage hours, not at idle - idle metrics hide the real bottlenecks. Treat sustained CPU above 80%, available memory dropping below 20% of installed RAM, or % Disk Time above 90% as bottleneck indicators. Record these numbers before proceeding so you can prove the impact of later steps.
Set the High Performance power plan and processor scheduling
Prioritize performance over energy savings and tune processor scheduling for the workload.
Control Panel > Power Options (GUI) | powercfg (command line)Windows Server defaults favor energy efficiency. For production servers, switch to High Performance and, on Server Core, tune scheduling toward background services.
- Activate the High Performance power plan:
- Confirm the active plan with
powercfg /getactivescheme. - On Server Core hosting background services, check the current scheduling value:
If it returns 2 (optimized for programs), set it to 18 for background services:
- Reboot to apply the scheduling change:
Restart-Computer -Force.
powercfg /setactive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635cKeep Win32PrioritySeparation at 2 on GUI servers running interactive applications - 18 favors background services at the cost of foreground responsiveness. The scheduling change requires a reboot, so perform it during a maintenance window. Some hardware exposes vendor-specific power profiles in BIOS/UEFI that can override the OS plan; if performance still looks throttled, check firmware power settings.
Optimize memory and disable unnecessary services
Free RAM and reduce background overhead from services the server doesn't need.
services.msc > (select service) > Properties > Startup type: DisabledReclaim memory by finding heavy processes and disabling non-essential services for your roles.
- Rank running processes by working set:
- Open the Services console with
services.mreadysc... runservices.mscto review services interactively. - Disable commonly unused services only after confirming they aren't required by your roles: Print Spooler, Fax, Windows Search, Tablet PC Input Service, and Windows Media Player Network Sharing Service.
- Disable them programmatically with the script in the command block.
$servicesToDisable = @('Spooler','Fax','WSearch','TabletInputService','WMPNetworkSvc')
foreach ($service in $servicesToDisable) {
$svc = Get-Service -Name $service -ErrorAction SilentlyContinue
if ($svc -and $svc.Status -eq 'Running') {
Stop-Service -Name $service -Force
Set-Service -Name $service -StartupType Disabled
Write-Host "Disabled service: $service"
}
}Never disable services blindly. Print Spooler is required for print servers; Windows Search is required where file indexing is used; some monitoring and backup agents depend on services that look idle. Verify against your installed roles first. Confirm results with Get-Service | Where-Object {$_.Status -eq 'Stopped' -and $_.StartType -eq 'Disabled'} and re-check Get-Counter "\Memory\Available MBytes".
Implement storage performance optimization
Reduce disk latency and configure disks correctly for their media type.
Storage is often the biggest bottleneck. Tune it per media type and layout.
- Check disk latency and queue length:
- Identify media types:
Get-PhysicalDisk | Select-Object DeviceID, MediaType, Size, HealthStatus, OperationalStatus. - For HDDs only, run
defrag C: /O /V. Never defragment SSDs. - On SSDs, verify TRIM:
fsutil behavior query DisableDeleteNotify. If it returns1, enable TRIM with the command below. - Find misaligned partitions:
Get-Partition | Select-Object DriveLetter, Offset, Size | Where-Object {($_.Offset % 1048576) -ne 0}. - For database servers, separate data, logs, and tempdb onto different physical drives (e.g.
New-Item -Path "D:\SQLData" -ItemType Directory -Force).
fsutil behavior set DisableDeleteNotify 0Warning: defragmenting an SSD reduces its lifespan - always confirm MediaType before running defrag. Enabling write-back caching (Get-PhysicalDisk | Set-PhysicalDisk -WriteCachePolicy WriteBack) improves throughput but risks data loss on power failure, so only enable it with UPS or battery-backed controller protection. This step changes disk configuration - ensure your backup is current first.
Update drivers and firmware for optimal hardware performance
Replace generic Windows drivers with vendor drivers to get full hardware performance.
OEM drivers generally outperform Microsoft's generic drivers on server hardware.
- Inventory driver versions and dates:
2. Identify your server model and BIOS: Get-WmiObject -Class Win32_ComputerSystem | Select-Object Manufacturer, Model and Get-WmiObject -Class Win32_BIOS | Select-Object SMBIOSBIOSVersion, ReleaseDate. 3. Download the latest drivers/firmware from your vendor: - Dell: Dell Command | Update or support.dell.com - HPE: HPE Smart Update Manager or support.hpe.com - Lenovo: Lenovo System Update or support.lenovo.com 4. Prioritize vendor NIC drivers, then enable Receive Side Scaling using the command below. 5. Check storage controller drivers (important for RAID): Get-WmiObject -Class Win32_SCSIController | Select-Object Name, DriverVersion, DriverDate.
Set-NetAdapterRss -Name "*" -Enabled $trueVerify no outdated drivers remain after reboot with Get-WmiObject Win32_PnPSignedDriver | Where-Object {$_.DriverDate -lt (Get-Date).AddMonths(-6)}. Firmware/BIOS updates can require downtime and are riskier than driver updates - schedule them in a maintenance window and confirm you have a rollback plan. Set a recurring (e.g. quarterly) driver-review schedule so drivers don't silently drift out of date.
Configure advanced network performance settings
Maximize throughput and lower CPU overhead for network-heavy workloads.
Tune the NIC and TCP stack for high-throughput, virtualization, or replication workloads.
- Review adapter state:
Get-NetAdapter | Select-Object Name, LinkSpeed, FullDuplex, State. - Enable Jumbo Frames (only with end-to-end switch/router support):
Set-NetAdapterAdvancedProperty -Name "*" -DisplayName "Jumbo Packet" -DisplayValue "9014". - Enable Receive Window auto-tuning:
netsh int tcp set global autotuninglevel=normal. - Enable RSS and interrupt moderation:
netsh int tcp set global rss=enabledandSet-NetAdapterAdvancedProperty -Name "*" -DisplayName "Interrupt Moderation" -DisplayValue "Enabled". - On Hyper-V hosts, enable VMQ with the command below and SR-IOV where hardware supports it (
Get-VMSwitch | Set-VMSwitch -IovEnabled $true). - Validate connectivity with
Test-NetConnection -ComputerName [target] -Port 445 -InformationLevel Detailed.
Set-NetAdapterVmq -Name "*" -Enabled $trueWarning: Jumbo Frames require every device in the path (NICs, switches, routers) to support the same MTU - a mismatch causes fragmentation and connectivity failures, so test immediately after enabling. SR-IOV and VMQ only help where the physical NIC supports them; verify support before enabling. [target] in the test command is a placeholder - replace it with a real host or IP. Some advanced-property display names vary by NIC vendor and driver, so confirm the exact name before scripting across many adapters.
Set up performance monitoring and alerting
Keep optimizations effective and catch regressions before users are affected.
Task Scheduler > Task Scheduler Library | Windows Admin Center (browser)Establish ongoing monitoring so you can spot drift against the baseline you captured in step 1.
- Install Windows Admin Center for centralized monitoring by downloading the MSI from
https://aka.ms/WACDownloadand running it withmsiexec /i <path> /quiet. - Create a scheduled daily monitoring script that samples core counters and exports a
.blg. Save the script toC:\Scripts\DailyMonitoring.ps1. - Register it as a scheduled task that runs daily, using the command block below.
- Export recent critical system events for review:
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-File C:\Scripts\DailyMonitoring.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At "12:00AM"
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
Register-ScheduledTask -TaskName "Daily Performance Monitoring" -Action $action -Trigger $trigger -Settings $settings -RunLevel HighestMake sure the C:\Scripts and C:\PerfLogs (or C:\Logs) folders exist before registering the task, or the script will fail silently. Use the baseline from step 1 as your normal-operations reference - a common practical threshold is alerting when a metric exceeds ~150% of baseline. For alerting, extend the script with SMTP email via Send-MailMessage or your monitoring platform's webhook.
Confirming Your Performance Optimizations Took Effect
After completing all seven steps, verify that each change persisted - several of them survive only after a reboot, and a few (power plan, processor scheduling, TRIM) are easy to silently revert. Treat this as a checklist rather than a single command: confirm the active power plan, the Win32PrioritySeparation value, the set of disabled services, the TRIM setting, and that your monitoring job is registered and running.
Start with the power plan, since it is the main command and the most common thing to slip back to a balanced profile after updates or Group Policy refreshes:
unknown nodeThen spot-check the other layers:
- Processor scheduling -
Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\PriorityControl" -Name Win32PrioritySeparationshould return18on background-service (Server Core / infrastructure) hosts, or remain2on GUI servers running interactive apps. - Disabled services -
Get-Service | Where-Object {$_.Status -eq 'Stopped' -and $_.StartType -eq 'Disabled'}should list the services you chose to disable. - Available memory -
Get-Counter "\Memory\Available MBytes"should show a measurable increase versus your baseline sample from Step 1. - Storage latency -
Get-Counter "\PhysicalDisk(*)\Avg. Disk sec/Read"should read under 1ms for SSDs and under 15ms for HDDs. - TRIM -
fsutil behavior query DisableDeleteNotifyshould return0for SSD volumes. - Monitoring - the scheduled task
Daily Performance Monitoringshould appear in Task Scheduler and produce.blgfiles underC:\PerfLogs.
The goal is not merely that the commands ran, but that utilization during peak hours has dropped below the 80% sustained threshold you flagged in Step 1. Re-run your Step 1 baseline sample during a busy period and compare - that is the real measure of whether the configuration is working, not the individual toggle states.
powercfg /getactiveschemereports the High Performance GUID (8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c);Win32PrioritySeparationholds the value you set (18 for background services, 2 for interactive); disabled services show Stopped/Disabled; TRIM query returns 0 on SSDs; available memory is higher than baseline; disk latency and interrupt time are within target; and the daily monitoring task is registered and writing logs. Peak-hour CPU, memory, disk, and network utilization no longer stay above 80%.- The active scheme reverted to Balanced,
Win32PrioritySeparationshows an unexpected value, disabled services are running again, or the scheduled task is missing - indicating a change did not persist across reboot or was overridden by Group Policy. If peak-hour utilization is still pinned above 80% on a resource, the true bottleneck may be hardware capacity or a specific workload rather than OS tuning; revisit Step 1 to re-identify which resource is constrained. - Expected output of powercfg /getactivescheme after Step 2.
- Optimized for background services; a return of 2 means the change did not apply or the host is intentionally left in the interactive default.
- 0 means TRIM is active. A return of 1 means TRIM is disabled and should be re-enabled with fsutil behavior set DisableDeleteNotify 0.
- Sustained below 80% during a busy period confirms the CPU is no longer a bottleneck after tuning.
Troubleshooting
The High Performance power plan does not appear or fails to activate with powercfg
Cause: Some power schemes are hidden by OEM firmware settings, or the platform is running under a hypervisor/host that overrides guest power policy. The GUID may also not be present until power schemes are restored.
Run powercfg /list to confirm which schemes exist. If High Performance is missing, restore the default schemes with powercfg -restoredefaultschemes, then re-run powercfg /setactive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c. On virtual machines, set the performance/power policy at the host level, since guest power plans have limited effect.
Applications become less responsive after changing Win32PrioritySeparation
Cause: A value of 18 optimizes CPU quantum for background services, which can penalize foreground/interactive applications on GUI servers.
For GUI-based servers running interactive workloads, set the value back to 2 with Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\PriorityControl" -Name Win32PrioritySeparation -Value 2 and reboot. Only use 18 on Server Core or dedicated background-service roles.
Disabling a service breaks a server role or dependent application
Cause: A service on the disable list (for example Windows Search or Print Spooler) is actually required by an installed role, feature, or line-of-business app on that specific server.
Re-enable the service with Set-Service -Name <ServiceName> -StartupType Automatic and Start-Service -Name <ServiceName>. Before disabling, always confirm the service is not needed for your roles, and test changes in a maintenance window rather than in bulk on production.
Running defrag on an SSD or losing data after enabling write-back caching
Cause: Defragmentation adds unnecessary write cycles that shorten SSD lifespan, and write-back caching can lose in-flight data if the server loses power without battery/UPS protection.
Verify media type first with Get-PhysicalDisk | Select-Object DeviceID, MediaType and only run defrag on HDDs. Ensure TRIM stays enabled on SSDs (fsutil behavior query DisableDeleteNotify returns 0). Only enable write-back caching on systems protected by a UPS or a battery-backed RAID controller.
Enabling Jumbo Frames causes dropped connections or fragmentation
Cause: Jumbo Frames require end-to-end support; if switches, routers, or the other endpoint are not configured for the same MTU, packets are fragmented or dropped.
Confirm every device in the path supports the same Jumbo Packet size before enabling. After setting it, validate with Test-NetConnection -ComputerName <target> -Port 445 -InformationLevel Detailed. If connectivity fails, revert the adapter's Jumbo Packet setting to the default (disabled/1514).
Network offload settings (RSS, TCP offload) reduce rather than improve throughput
Cause: Some NIC/driver combinations handle offload features poorly, or interrupt moderation and offload are misconfigured for the workload, moving load unexpectedly onto a single core.
Confirm you are running the vendor NIC driver, not the generic Windows driver, then re-test. Check that RSS is enabled with Get-NetAdapterRss and monitor \Processor(*)\% Interrupt Time - it should stay below about 10% under normal load. If a feature degrades performance, disable it on that adapter and re-measure.
Frequently asked questions
What power plan should I use on Windows Server 2025 for best performance?
Use the High Performance power plan for production servers, since the default balanced settings prioritize energy efficiency over throughput. Activate it with powercfg /setactive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c and confirm with powercfg /getactivescheme.
Is it safe to defragment SSDs on Windows Server 2025?
No - defragmenting an SSD provides no performance benefit and shortens its lifespan by adding unnecessary write cycles. Verify the media type with Get-PhysicalDisk first, run defrag only on HDDs, and keep TRIM enabled on SSDs by ensuring fsutil behavior query DisableDeleteNotify returns 0.
Which Windows Server services can I safely disable to improve performance?
Commonly safe candidates include Print Spooler (if no printing), Fax, Windows Search (if not indexing), Tablet PC Input Service, and Windows Media Player Network Sharing Service. Always confirm none of them are required by your installed roles before disabling, and test in a maintenance window since disabling a dependency can break an application.
How do I identify a CPU, memory, disk, or network bottleneck on Windows Server?
Sample the key counters during peak hours using Get-Counter "\Processor(_Total)\% Processor Time","\Memory\Available MBytes","\PhysicalDisk(_Total)\% Disk Time". Sustained CPU above 80%, available memory below 20%, or disk time above 90% indicates the constrained resource.
Do OEM drivers really perform better than the built-in Windows drivers?
Yes - vendor drivers from Dell, HPE, or Lenovo are tuned for their specific server hardware and generally outperform Microsoft's generic drivers, particularly for network adapters and storage controllers. Inventory versions with Get-WmiObject Win32_PnPSignedDriver and install the latest OEM packages for your model.
How do I monitor Windows Server 2025 performance over time?
Install Windows Admin Center for centralized monitoring and create Performance Monitor data collector sets, then automate a daily Get-Counter script with a scheduled task that exports .blg logs. Establish a baseline during normal operations and alert when metrics exceed roughly 150% of baseline.





