The Problem That Broke My Batch System

Last spring I was running a batch action for an e-commerce client, about 300 product shots that needed consistent edge softening applied to composited shadows. The action had worked perfectly for weeks. Then one morning it started producing brushstrokes at wildly inconsistent sizes across different files. Some shadows looked like they were painted with a mop. Others were a single pixel line.

The culprit was a custom brush I’d built months earlier without thinking carefully about how it would behave when document resolution changed. At 300 DPI it was fine. At 72 DPI it was chaos. I lost about three hours tracking that down, which still stings when I look at my workflow savings spreadsheet.

That experience made me properly obsessive about brush construction, specifically about building brushes that stay predictable inside actions, scripts, and batch processes. Here is what I know now.

Why Brush Behavior Is More Fragile Than You Think

Photoshop brushes are resolution-dependent by default. When you record an action that applies a brushstroke, the playback size is expressed in pixels, not percentages of the document. So a 200-pixel brush recorded on a 300 DPI file becomes comically small on a 3000 DPI print file, or grotesquely oversized on a 72 DPI web asset.

There is also the dynamics problem. Any brush with Size Jitter, Scatter, or Angle Jitter tied to pen pressure or stylus tilt will behave differently on a machine running the action without a tablet connected. I have had actions played back by clients on trackpad laptops that produced nothing because the brush opacity was 100% pressure-dependent and a mouse registers zero pressure.

Understanding this means you need to make deliberate decisions before you build: is this brush for manual use, automated use, or both? The answer changes almost every setting you’ll choose.

Building the Base Shape for Automation

Start with a new document sized at exactly 2500 x 2500 pixels, 72 DPI, grayscale. The size gives you enough detail without inflating the preset file. Work in grayscale because brush tips read luminosity, not color. Black areas apply full paint, white areas apply nothing, and gray values create partial transparency. This is all Photoshop needs.

For a general-purpose soft edge brush built for batch use, paint your shape with a hard round brush at 100% opacity, then apply a Gaussian Blur between 8 and 15 pixels to control the falloff. Harder edges need less blur. Feathered shadow effects might want 20 to 25 pixels. Avoid Filter > Blur > Lens Blur here. It introduces depth-map artifacts that show up as ugly halos at some brush sizes.

Once the shape is ready, go to Edit > Define Brush Preset. Name it something specific: “SoftEdge-Shadow-2500px” beats “my brush 3.” Go immediately to the Brush Settings panel and set Size Jitter to 0%, turn off all pressure-dependent controls, set Spacing to 1% for smooth continuous strokes or 25% for deliberate stamp-style application. Save the full tool preset, not just the tip, using the Tool Presets panel. Tool presets store your opacity, flow, and blending mode alongside the tip, which is what you actually want recorded in an action.

Making Size Work Across Resolutions

The pixel-dependency problem has two practical solutions, and I use both depending on the job.

The first is to record your action at the resolution you use most. If 90% of your files are 300 DPI product shots, build and record everything at 300 DPI. Add a step at the start of the action that converts the document to 300 DPI using Image > Image Size with Resample turned off. This normalizes the canvas before your brushwork fires, then you can convert back afterward if needed.

The second approach is to use Script Events or a JSX script to calculate brush size as a percentage of the document’s short edge before applying it. This takes about 20 lines of JavaScript and is genuinely worth learning if you process files at mixed resolutions regularly. I built my first action at 26, kept everything manual for years after that, and the day I learned basic scripting was the day my batch throughput roughly doubled. The brush-size calculation script alone probably recovered its writing time within two weeks.

Texture Brushes and the Grain Trap

Texture brushes, the kind with paper grain, canvas weave, or noise built into the tip, cause a specific problem inside actions that catches people off guard. If the texture source is set to anything other than “None” or a fixed pattern from your Presets library, it can pull from a pattern that simply doesn’t exist on another machine or in another session. The action plays back silently, with no error, but the texture is gone.

If you need texture in an automated brush, bake it into the brush tip itself rather than using the Texture panel inside Brush Settings. Apply your grain or noise directly to the grayscale source document before defining the preset. Slightly heavier than you think looks right, because brush opacity and flow will soften it during application. A tip that looks too crunchy at 100% view usually lands correctly at the working opacity you’ll set in the tool preset.

The Texture panel in Brush Settings is excellent for manual painting. For anything that needs to survive a batch process on someone else’s machine, it’s a liability.

The Stability Test Before You Save Anything

Before any brush goes into a production action, I run it through what I call the three-file check. I apply it to a 72 DPI web file, a 300 DPI print file, and a 150 DPI mid-range file. All three get the same action, and I compare the visual weight of the result. If the stroke reads as the same relative size and softness across all three, the brush is stable enough to ship. If not, I go back and resolve the resolution dependency before it costs me a client deadline.

A brush that works perfectly once is not a production asset. A brush that works correctly the hundredth time, on a different file, on a different machine, is worth building an entire workflow around.