Texture updates not appearing for 1 frame?

I have a texture - a sprite sheet, really, that gets updated over time periodically (not every frame), and then those updated portions are drawn in the same frame. When this happens, I frequently see one frame of garbage for the updated sprites, where I think the texture’s old data is displayed instead of the new data. This is not a question about upload speed: I’m following common advice for the fastest image format (32-bit BGRA, even though I don’t need nearly that much precision) and fastest technique for updating the texture (glTexSubImage2D).

I instantiate the texture object like this:

	glGenTextures(1, &originalTexture);
	glBindTexture(GL_TEXTURE_RECTANGLE, originalTexture);
	glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexImage2D(
			GL_TEXTURE_RECTANGLE,
			0,
			GL_RGBA8,
			atlas.Width,
			atlas.Height,
			0,
			GL_BGRA,
			GL_UNSIGNED_INT_8_8_8_8_REV,
			nullptr);

Then, I update it as needed at the start of a frame like this:

		glBindTexture(GL_TEXTURE_RECTANGLE, originalTexture);
		glTexSubImage2D(
			GL_TEXTURE_RECTANGLE,
			0,
			0,
			0,
			atlas.Width,
			atlas.Height,
			GL_BGRA,
			GL_UNSIGNED_INT_8_8_8_8_REV,
			atlas.getData());
		glBindTexture(GL_TEXTURE_RECTANGLE, 0);

I’ve tried on Windows with both Intel and Nvidia cards as well as on macOS with an AMD card, and I see the same behavior.

What am I doing wrong?

In case it matters, I use a version 3.3 Core Profile context, 24-bit color, 8-bit depth, 16-bit stencil, and double buffering.

Looks OK, are you sure you are swapping correctly when you think you are and not triple buffering? Try reading the backbuffer right after the draw as a test. Check your subsequent bind as this should be immediately available after that subload.
Try loading a test pattern instead of null data when you create it just to help debug. You needn’t preserve image size between loads unless you are subloading, I expect your goal here is preallocation, YMMV, but no need for a full size image in your test/debug pattern if you replace that subload with a full load with internal format. I doubt you’re saving much with a full image subload and I’d at least try replacing it with a load since you’re not actually subloading. If you are subloading an atlas then I’d expect an atlas offset x and y and a larger width on the initialization.