Jul 12, 2026

Windows Network Optimization for Gaming and Low Latency

Windows Network Optimization for Gaming and Low Latency

Disclaimer: This article is based on our own independent research and testing. If you find an inaccuracy or a mistake, feel free to reach out to us.

In this article, you will find our recommendations and ways to optimize your Windows network configuration for gaming and low-latency applications like CS2.

Start by creating a restore point in case you want to revert the changes in this guide. When you are done, update your network adapter driver to the latest version.

Update Your Network Adapter Driver

We will update our drivers from the adapter manufacturer's website and NOT the motherboard manufacturer's website, because based on our own testing, proper RSS configuration only worked by installing the latest drivers directly from the manufacturer.

In our case, we will use a PCI Marvell adapter:

PCI Marvell network adapter used for Windows network optimization

When you are done installing the latest driver, reboot your PC and launch TCP Optimizer.

Reset Your Existing Settings with TCP Optimizer

You may have followed a networking guide in the past and used TCP Optimizer, so just to be safe, let's reset it.

Link here: TCPOptimizer.exe

Run the app as admin, find your network adapter (or click Modify All Adapters), select Windows Default, and apply the changes.

TCP Optimizer Windows default reset for network optimization

The app will show a window. Press OK, and when it is done, restart your PC.

Check RSS and the Indirection Table

When you are back in Windows, open a PowerShell window as admin and type:

Get-NetAdapterRss

This is the expected default result for our network adapter:

Get-NetAdapterRss PowerShell output showing RSS indirection table buckets

Your indirection table must be populated (buckets). This confirms that an RSS mapping exists.

If you still do not see the indirection table populated properly, you have three options:

  1. If you used DisableTaskOffload in the past, remove the key from Registry Editor by running this in Command Prompt:
    reg.exe delete "HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" /v DisableTaskOffload /f
    Then restart your PC.
  2. If you use ExitLag, disable their filter and use WFP. Read this first and use WFP in ExitLag:
    ExitLag WFP filter setting to fix empty RSS indirection table
  3. Your network adapter does not support RSS or MSI-X.

What the RSS values mean

We now need to have a basic understanding of what we see in the image above.

  • Base processor is the lowest processor address in the RSS processor array. The base processor group and base processor number together define the lower boundary of the processor range available to RSS.
  • Max processor is the highest processor address in the RSS processor array. The maximum processor group and maximum processor number together define the upper boundary of the processor range available to RSS.
  • Max processors is the maximum number of logical processors that RSS can use concurrently from the RSS processor array for a single network adapter.
  • RSS processor array is the set of logical processors that are eligible for RSS processing on the network adapter.
  • Indirection table is the list of buckets that decides which logical processor will handle each network connection.

These terms may seem complicated at first, but they are actually very easy to understand.

How to Set Up RSS

Assuming you can see the indirection table properly, we will now configure your adapter to use RSS properly.

We will break it down into two categories:

  1. The affinity
  2. The queues (lanes)

In our case, 2 queues are a good starting point for gaming and normal browsing (or even streaming). This is not a fixed rule for every workload and use case. For gaming alone, increasing RSS queues beyond the default is usually unnecessary. However, if you regularly perform high-speed network file transfers, increasing the number of RSS queues to 4 will improve throughput.

RSS queues explained: the highway example

You can imagine RSS queues like a highway with 2 lanes: a left lane and a right lane.

One lane can handle CS2's traffic and the other can handle YouTube's traffic. But the lanes are shared; they are not reserved for specific apps. Both YouTube and CS2 can also end up in the same lane, no matter how many lanes (queues) you have.

With RSS enabled, incoming packets belonging to CS2’s main UDP flow are normally mapped to one receive queue at a time.

Why?

Because the connection stays the same. Your IP, the server's IP, the ports, and the protocol don't change while you're in the match.

When RSS hashes that traffic, it creates a hash (think of it like an ID). Since the connection stays the same, the hash stays the same too.

Same hash = same lane. So your gameplay packets keep going to the same RSS queue instead of jumping between different ones.

This lane normally won't change during the match. It would only change if the connection changes, like reconnecting to the server or changing your RSS configuration.

Other traffic, like YouTube, Discord, Steam downloads, or your browser, can use different lanes or even the same lane as CS2, depending on how RSS hashes those connections.

ISR and DPC processing

Our goal is to optimize the lanes as well as the interrupt and receive processing around them. Your network card interrupts the processor because it got new information. The first part is handled by an ISR, and the heavier follow-up work is handled by a DPC. A DPC is not another hardware interrupt; it is deferred work that Windows schedules after the ISR.

The ISR is the light part. It tells the CPU, "Hey, I got a new packet." DPCs are the ones that do the heavier lifting. They allow Windows to save that work for a moment later, so the CPU can quickly handle the initial interrupt first.

So what do we need to do? On an RSS adapter using MSI-X, Windows normally keeps the ISR and its related DPC work on the same processor. The affinity setting below does not create RSS queues. It only limits which logical processors the adapter's interrupts are allowed to use. We will align that processor range with the RSS processor range we configure later.

Set the Interrupt Affinity

This is an optional tuning step, not a requirement for RSS, but we suggest following along.

Download the Microsoft Interrupt Affinity Tool.

Extract it and run the X64 version as administrator. Scroll down and find your network adapter. Ours is the Marvell one:

Microsoft Interrupt Affinity Tool with CPU 12 and 14 checked for network adapter

Click Set Mask. We will limit the adapter interrupts to the same 2 logical processors that we plan to allow RSS to use. Checking 2 boxes does not create 2 RSS queues; PowerShell controls the queue count later. For us, to keep it simple, we will check 12 and 14.

The boxes are logical processors. With SMT/Hyper-Threading on, every even box is a physical core and every odd box is its SMT thread (core = box number / 2). Boxes 12 and 14 are physical cores of our 9800X3D. They are core 6 and core 7, the last two cores of our 8-core system (count starts from zero!). Core 6 and core 7 will be our 2 lanes. Feel free to copy our setup if you have an 8-core system.

Keep in mind that you must not assign an affinity to E-cores. On hybrid Intel CPUs, the last boxes are assigned to the E-cores. To keep it simple, you can use the third and fourth physical cores, core 2 and core 3 (count starts from zero!). With Hyper-Threading on, that means you check boxes CPU 4 and CPU 6. If Hyper-Threading is off, the boxes match the cores directly, so check CPU 2 and CPU 3.

Then press OK and Done. Your adapter will now restart.

Assign the RSS Queues with PowerShell

Now we are moving to the important part: assigning the RSS queues with PowerShell.

The formula is this:

Set-NetAdapterRss -Name "NAME_OF_ADAPTER" `
  -BaseProcessorNumber START -MaxProcessorNumber END -MaxProcessors PROCESSOR_NUM `
  -NumberOfReceiveQueues QUEUE_NUM -Profile NUMAStatic
  • NAME_OF_ADAPTER = your network adapter's name from PowerShell (get it from Get-NetAdapterRss)
  • START = the first box you checked, or the first logical processor you want RSS to use if you skipped the affinity step
  • END = the last box you checked, or the last logical processor you want RSS to use if you skipped the affinity step
  • PROCESSOR_NUM = the maximum number of processors RSS can use at the same time (2 in our case)
  • QUEUE_NUM = the number of RSS queues we want to test (2 in our case)

NUMAStatic keeps this mapping static. We use it because this guide is testing a fixed processor range.

So the final command for us is:

Set-NetAdapterRss -Name "Ethernet 2" `
  -BaseProcessorNumber 12 -MaxProcessorNumber 14 -MaxProcessors 2 `
  -NumberOfReceiveQueues 2 -Profile NUMAStatic

And the result is this:

Set-NetAdapterRss result with 2 RSS queues configured on cores 12 and 14

As expected, Windows accepted the RSS configuration we asked for:

  • BaseProcessorNumber is 12
  • MaxProcessorNumber is 14
  • MaxProcessors is 2
  • NumberOfReceiveQueues is 2

And most importantly, our indirection table is populated as well.

Optimize the Network Adapter Settings in Device Manager

Now, let's open the network adapter's settings.

Open Device Manager and find your network adapter.

Network adapter in Windows Device Manager

Find Power Management and uncheck "Allow the computer to turn off this device to save power".

Network adapter Power Management tab with the device power-saving option unchecked

Then head to the Advanced tab.

You will see many options, but we will focus on these:

  • Energy-Efficient Ethernet
  • Interrupt Moderation
  • Interrupt Moderation Rate
  • Receive Buffers
  • Transmit Buffers
  • TCP/UDP Checksum Offload (IPv4)
  • TCP/UDP Checksum Offload (IPv6)
  • Recv Segment Coalescing (IPv4)
  • Recv Segment Coalescing (IPv6)
  • Large Send Offload V1 (IPv4)
  • Large Send Offload V2 (IPv4)
  • Large Send Offload V2 (IPv6)

Energy efficiency

Feel free to turn any power-efficient setting off.

Interrupt Moderation

Interrupt Moderation reduces how often the adapter interrupts the CPU by handling multiple packets with a single interrupt. When enabled, this lowers CPU overhead but can add a tiny amount of delay (microseconds). For real-time applications like games, we suggest turning Interrupt Moderation off.

Receive and Transmit Buffers

Receive Buffers and Transmit Buffers are related as well, but your receive buffers do not have to be double the transmit buffers. There is no universal ratio or rule that dictates that. On our own adapter, the minimum transmit buffer value is double the minimum receive buffer value.

For example, at 128 receive buffers, the NIC has 128 receive descriptors ready to receive incoming packets. Each descriptor tells the NIC where to place an incoming packet in memory.

In our testing, we dropped Transmit and Receive to the lowest values exposed via Device Manager's UI while testing streaming and CS2 at the same time and noticed no performance degradation, hitching, packet loss, or jitter. Keep in mind that not every adapter and firmware handles traffic the same way. This is why we urge you to do your own testing and validation.

Lower values can reduce queued work on some setups, but they can also run out of descriptors during bursts, so do not keep them only because the number looks lower.

Fun fact: back in 2020 with our 2700X and 1660 Ti, we would have severe performance degradation and stutter just before an execute on B site on Inferno. Lowering the receive and transmit buffers to the adapter's lowest allowed value completely solved the issue.

Can you believe that 2020 was 6 years ago? Feels like yesterday. Makes us feel.... i do not know... somehow...

Offloading

The following features are all related to offloading:

  • TCP/UDP Checksum Offload (IPv4): Lets the network adapter calculate and verify checksums for IPv4 traffic instead of the CPU.
  • TCP/UDP Checksum Offload (IPv6): Does the same for IPv6 traffic.
  • Large Send Offload V1 (IPv4): Lets the network adapter split large outgoing IPv4 TCP packets into smaller packets instead of the CPU.
  • Large Send Offload V2 (IPv4): A newer version of LSO that handles larger outgoing IPv4 TCP packets more efficiently.
  • Large Send Offload V2 (IPv6): Does the same for outgoing IPv6 TCP packets.

We will only focus on TCP/UDP Checksum Offload (IPv4) and TCP/UDP Checksum Offload (IPv6), since they work with both UDP and TCP packets. Large Send Offload only applies to TCP.

We suggest leaving TCP/UDP Checksum Offload enabled. Checksum offload is a dependency for other features, so disabling it can also disable RSC and LSO, and on some drivers it can break RSS as well. Only turn it off temporarily when testing a known adapter or driver problem, and run Get-NetAdapterRss again afterward to confirm RSS still works.

Disabling or enabling TCP/UDP Checksum Offload does not break DPC and ISR placement.

Coalescing

  • Recv Segment Coalescing (IPv4): Combines multiple incoming IPv4 packets before sending them to the CPU, reducing CPU work.
  • Recv Segment Coalescing (IPv6): Does the same for incoming IPv6 packets.

Receive Segment Coalescing is a feature that applies to TCP traffic, not your game's UDP packets. Feel free to leave this setting at its default value.

This article will be updated later on with more data.