Understanding RAM Timings

RAM timings influence performance by controlling memory latency. Learn how they work.

My Version of Explaining RAM Timings

Most highly ranked websites and forums discussing RAM timings have this "wooden" feel—packed with engineering jargon that reads like someone copied it straight from a JEDEC specification PDF without fully understanding it. And let’s be honest, engineers do love sounding smart.

While I do "engineer" things (like, you know, building this website from scratch), I’m not a fan of pretentious speech. What you’ll find here is a down-to-earth explanation of RAM timings—what they do, how they connect, and why they matter. No exam-style lectures, just practical insights you can actually use.

I hope you enjoy my writing and maybe even learn something new along the way. And if it doesn’t all click immediately, don’t worry—you’re not alone. Even after years of working with RAM (albeit just on my own household computers), I still come across things I misunderstood or overlooked. Tuning RAM is a journey, and I hope this guide serves as a useful reference for yours.

Primary Timings

tRCD (Row Address to Column Address Delay)

Even though tCL (CAS Latency) is the most commonly referenced timing, tRCD (or rather tRCDRD for its full name) is actually the first delay that occurs when accessing memory. tRCD defines the time required to activate a row before column access (READ or WRITE) can occur. But what does "activate" mean? It refers to the time needed to copy the row's data into a buffer inside the RAM module. Only after this activation completes can the data be accessed by issuing a READ or WRITE command.

From experience, while lowering tRCD can improve performance, it is often already maxed out in the XMP profile for most memory kits. If you can successfully reduce tRCD without instability, it’s a major win in memory tuning. However, in most cases, tRCD is a hard limit based on the RAM's physical characteristics, and significant reductions are unlikely.

CAS Latency (CL)

Now that the row is activated and ready to be accessed, a READ command moves data onto the data bus. The time required for the data to become available is determined by the infamous tCL (CAS Latency). This timing represents the number of cycles needed before the first columns of data are available, with DDR transferring two columns per cycle.

For each READ command, 8 columns are fetched over 4 cycles. This means that a tCL of 16 effectively results in 19 cycles, as the final group of columns is read at cycle 19.

tRTP (Read to Precharge Time)

This defines the minimum delay between a READ command and the subsequent PRECHARGE command. When a READ occurs, we first wait tCL cycles before the first columns of data appear on the bus. If we intend to close the row immediately after this READ, tRTP determines how long we must wait from the moment data starts transferring to when we can issue a PRECHARGE command. Since data transfer takes multiple cycles, part of tRTP overlaps with this process. For example, if tRTP is 12:

  • The first two columns of data might be read at cycle 1.
  • The last two columns might be read by cycle 4.
  • The remaining 8 cycles ensure stability before the row can be closed.
tRTP ensures that the internal sense amplifiers and row buffers have enough time to settle before precharging the row. Setting this value too low could lead to instability or corruption when switching to the next operation.

tRP (Row Precharge Time)

tRP (Row Precharge Time) defines the time required to deactivate an open row before accessing a new one. Once READ operations are complete and tRTP has expired, the row can be closed, meaning its data is written back into the capacitors. This process is governed by tRP.

tRP is a critical timing because failing to wait long enough for this process to complete can result in immediate data corruption. Ensuring a proper tRP value allows stable and efficient memory operation.

tRAS (Row Active Time)

This is the minimum time a row must remain active before it can be precharged. At first glance, this might seem like an interesting yet somewhat redundant timing. tRAS defines the minimum delay between an ACT (Activate) and a PRE (Precharge) command. However, consider the sequence of operations involved in reading data:

  • Activating a row takes tRCD cycles.
  • Retrieving data from a read command requires tCL cycles.
  • After data starts arriving, we must wait tRTP cycles before things settle.

For example, with memory timings of 20-16-12:

  • We spend 40 cycles just to read 8 columns (64 bits).
  • If tRAS is set to 36, we’ve already exceeded this time just by issuing a READ command.

So why does tRAS exist if a single READ operation already takes longer? The key scenario where tRAS becomes relevant is when a row is activated but not read—meaning it will be precharged immediately. In such cases, tRAS ensures a minimum active period before precharge occurs. A common practice is setting it just slightly above tRCD, typically around 21 (the lowest value many BIOSes allow). For instance, if tRCD is 19, setting tRAS to 21 ensures at least 2 idle cycles before the row can be closed and prepared for another operation. That’s its main functional purpose at its minimum setting.

How it all works together

To access memory, we first activate a row. Then, we issue a READ command, which moves data onto the memory bus and from there to the CPU. If we want to perform another READ on the same row, we do not need to wait for tCL again—READ commands can be issued every tCCD cycles, typically 4. Given a row with 2048 columns, and assuming a burst length of 8 columns per READ, we need 256 READ commands to access the entire row. If issuing a new READ every 4 cycles, the full row is read in 1024 cycles. After the last READ, we wait tRTP cycles before issuing a PRECHARGE, which closes the row and allows access to another.

tCCD is a memory timing that is typically hidden in modern BIOS settings, as it is automatically managed by the memory controller. That’s why this is the only place I'll reference it.

When reading memory, 4 cycles is the minimum time required to issue a new READ command. This is because tCCD defines a 4-cycle delay, allowing each READ to fetch 8 columns per burst (BL8). As a result, we get a continuous stream of data, with no wasted cycles—assuming no bank conflicts or other delays interfere.

Secondary Timings

tRC

tRC (Row Cycle Time) is the minimum number of cycles required between two ACTIVATE commands on the same bank. It’s somewhat similar to tRAS in its behavior. Since tRC = tRAS + tRP, a row must remain open long enough before it can be precharged and activated again.

Using a memory configuration of 18-16-10-18, a single READ already consumes 62 cycles (opening, reading, transferring data, clearing, and closing the row). If tRC is set to 68 cycles, we are very close to the limit for just one read. With two reads, we almost completely reach this limit, ensuring that no unnecessary wait cycles occur.

Where tRC becomes a real bottleneck is when no reads occur. If a row is activated and then immediately precharged (without any READ operation), waiting the full tRC (e.g., 68 cycles) before issuing the next ACTIVATE results in wasted time. With a tRAS of 21 and a tRP of 18, this scenario already wastes 39 cycles without producing any useful data output (though the row gets refreshed).

A practical solution is lowering tRC to around 46-48 cycles, reducing wasted cycles. If a READ occurs, the system primarily relies on the existing memory timings (tRCD, tCL, tRTP) to ensure stability.

tRRD_l (Same Bank Group)

This is where things get interesting. So far, we’ve discussed reading memory from a single row, and we’ve seen that switching to a different row takes time. But RAM is designed for high-speed operation—so how does it handle this?

The answer lies in bank groups. Modern DDR4 memory organizes banks into groups of 4 banks, allowing multiple rows to be activated in parallel—one in each bank of the same group. The minimum delay between these activations is controlled by tRRD_l (Row-to-Row Delay, Same Bank Group).

In high-performance memory kits, tRRD_l can be as low as 4 cycles. This aligns with DDR's burst structure, where an 8-column READ completes in 4 cycles. By synchronizing row activations and READ commands in a staggered cascade, memory can sustain a high-speed data burst across multiple rows.

However, since data is being fetched from four different places in parallel, it needs to be merged into a single sequential data stream before reaching the CPU. This means the memory controller must carefully synchronize these parallel bursts, ensuring that they are delivered in a continuous, ordered one-dimensional array. This merging process prevents gaps in the data flow and maximizes memory bandwidth.

tRRD_s (Different Bank Group)

Just like tRRD_l, tRRD_s defines the minimum delay between two ACTIVATE commands—but this time, when activating rows in different bank groups. Since bank groups operate independently, the delay between activations is typically lower than tRRD_l, allowing for faster row activations when spreading memory accesses across multiple bank groups.

In modern DDR4 memory, bank groups are structured to improve parallelism, meaning we can activate rows in different groups with minimal interference. The tRRD_s delay is typically set to 4 cycles, which matches the minimum value of tRRD_l. This difference exists because accessing a new bank group reduces internal contention, but the memory still has to follow fundamental row activation constraints.

Just like before, activating multiple rows in parallel means that data is coming from different locations. However, because these rows belong to separate bank groups, the memory controller must still synchronize the bursts into a single ordered stream before delivering the data to the CPU. If properly managed, this technique ensures that memory bandwidth is fully utilized, reducing stalls and maximizing efficiency.

In an optimized scenario, tRRD_s allows faster activation across multiple bank groups, ensuring a steady flow of data. This is particularly useful in workloads that require frequent row switching while maintaining high throughput.

tFAW (Four Activate Window)

tFAW (Four Activate Window) is an interesting timing because it controls the time window in which four ACTIVATE commands can be issued. The primary reason for its existence is to limit power draw. Since activating a row consumes a relatively high amount of power (as it involves copying an entire row of data from capacitors to sense amplifiers), memory manufacturers implemented tFAW as a safeguard to prevent excessive energy consumption and heat buildup.

Here’s how it works. Let’s say we have tRRD (Row-to-Row Delay) set to 4 cycles and tFAW set to 16 cycles:

  • Cycle 0: First activation
  • Cycle 4 (previous cycle + tRRD): Second activation
  • Cycle 8: Third activation
  • Cycle 12: Fourth activation

Since we only took 12 cycles to activate four banks or bank groups, the fifth activation would normally occur at cycle 16, exactly when the tFAW window ends, allowing us to start a new sequence. However, if tFAW were set to 20 cycles, the fifth activation would be delayed until cycle 20, effectively adding 8 cycles of idle time instead of 4.

Now, let’s consider a scenario where tRRD is 5 cycles and tFAW remains at 16:

  • Cycle 0: First activation
  • Cycle 5: Second activation
  • Cycle 10: Third activation
  • Cycle 15: Fourth activation

Since all four activations still occur within the 16-cycle tFAW window, we’re fine. The fifth activation will occur at cycle 20, meaning our activations are more spread out compared to the previous case.

In essence, tFAW controls how aggressively RAM can be activated, impacting both power consumption and heat generation. While higher activation rates translate to better performance, they also result in increased energy usage and potential heat buildup. Most DDR4 and DDR5 RAM runs between 1.2V and 1.5V, depending on how the XMP profile is configured.

In practice, overheating isn’t a common issue—especially if your RAM modules have heatsinks and your CPU cooler provides sufficient airflow. However, if you're manually tuning these values, it's a good idea to monitor temperatures initially to ensure stability.

What It All Means?

While the primary timings we’ve covered can be tweaked to some extent, there’s only so much you can do within a single bank or row. The real magic of RAM performance comes from its ability to extract data in parallel. And that’s exactly where tRRD and tFAW come into play.

So, what’s the big deal? XMP profiles should have this covered, right? Well, in my experience—wrong. When I first checked my XMP-loaded settings, I found tRRD_l and tRRD_s set to 11 and tFAW at a staggering 40. That was my default configuration, and I had no idea until I dug deeper. Once I actually understood what these timings meant, I was able to drop them down to 5-5-16—a massive leap from 11-11-40. And probably one of the biggest discrepancies in RAM tuning.

Meanwhile, my primary timings were far less flexible. Lowering tRCD from 19 to 18 caused stability issues, and while I managed to bring tCL down from 17 to 16, that’s hardly a game-changer. Sure, I reduced tRC from 66+ to 54, and maybe I could push it even lower, but in real-world scenarios, especially when a READ is involved, the actual execution time is higher anyway.

But for tRRD and tFAW, the improvement was huge—and came with zero stability issues. I can run my work or my games for hours without a single misplaced column. So why isn’t this properly optimized in XMP profiles? That’s exactly why I built this entire website—to shed light on what really matters in RAM tuning.

What I Haven't Covered?

I haven’t talked about the Command Rate. It’s pretty boring—just the number of cycles a command is "held" before execution. It ranges from 1T to 2T, and at worst, wastes a cycle to improve stability. Not much to tweak there.

I also haven’t covered WRITEs. The only thing I changed was setting tRCDWR to 8—the lowest possible value. It worked fine with no issues, so I left it at that.

tRFC and refresh cycles are another thing I didn’t dive into. As far as I understand, my tRFC of 312 is already pretty aggressive, and I don’t think there’s much performance left to squeeze out of it.

And then there’s actual overclocking. Sure, tweaking timings is a kind of overclocking, but really, what we’re doing is tuning RAM closer to the performance it’s already capable of. We’re just telling the memory controller, "Hey, you can go lower," because—well, it can. We’re simply skipping wasted cycles.

But RAM frequency is a different story. My RAM runs at 1800 MHz, perfectly matched to my CPU memory clock. I could push both to 1900 MHz, but I don’t see any meaningful performance gain from it. However, if you have a different CPU architecture that isn’t as tightly coupled, or if you’re running 1600 MHz RAM and can push it to 1700 or even 1800 MHz while maintaining a 1:1 ratio with your CPU memory clock—then by all means, give it a shot.

Raising RAM voltage is another option. My memory runs at 1.35V, and while I could push it to 1.5V or even 1.55V, I prefer running a tight, safe setup rather than squeezing every last bit of performance from people... erh, I mean RAM.

That said, some people enjoy pushing the limits. If you have the time to tinker and test—go for it. Just remember, an unstable system can run fine for a whole day, only to crash at the worst possible moment. Personally, I’m just happy knowing my RAM isn’t wasting cycles like it did on the default XMP profile—while also knowing my computer won’t freak out when I’m in the middle of writing a long paragraph.


Alphadev RAM Simulator ©2025