I’m a couple of weeks into 3D printing with a Creality Ender 3 S1 Pro. My initial impressions are: tl;dr: mechanically good, firmware bad. Either install synman’s pro firmware (requires a screen downgrade) or klipper (drops the screen and requires a raspberry pi — I went with MainsailOS) and you’ll have a very good printer for the price.

Here’s my best 3D Benchy so far, printed in 55 minutes in PETG using Klipper


  • Mechanically solid and well built, comes very well packed, does not feel like the stereotypical “cheap chinese” product at all
  • Quick and easy to assemble (I recommend using loctite on all screws to prevent them coming loose from vibrations)
  • Some replacement parts available
  • Well supported with (mostly quite good) profiles available for various pieces of software
  • Touchscreen interface is fast and convenient to use if you’re satisfied with the stock firmware
  • Main board is not locked-down so it’s easy to install different firmware, and just as easy to revert to stock in the unlikely event that you want to


  • The stock firmware is very limited and has various problems.
    • Most notably, the “print on resume” feature causes uncontrollable pauses between layers, during which the nozzle will leak filament, causing huge blobs and stringing. Not possible to turn off in the UI, requires a M413 S0 command added to the start g-code in your slicer (or changing to a different firmware, which you should do anyway). Here’s a comparison of the exact same part with and without “resume on power loss” enabled, both printed back when I was using the stock firmware:
    • The auto bed leveling feels extremely unreliable and hard to trust
    • You can only see the first few characters of gcode files, so it’s impossible to differentiate between two similar files with different suffixes
  • Fiddly to perform firmware updates — screen and main board require separate files, sometimes in different folders depending on the chipset you have (which you can only check by opening the printer and looking at the hard-to-read MCU part number), always with a new filename otherwise it’ll fail silently, both will accept firmwares for different models with weird failure modes like a rotated screen
  • v-wheels riding in aluminium extrusions have a limited accuracy. Definitely good enough for a lot of purposes, but can warp and wear over time, will never be as good as precision-ground linear rods or (even better,) rails
  • XZ gantry arrived with loose Z nuts, causing huge amounts of Z kickback and preventing any kind of accurate movement. No indication that you have to tighten these in the instructions, and sources on the web inconsistent about what you should do about it. I ended up tightening mine up so they don’t rattle and have had no further issues.
  • Flex cable XZ clip position sticker was placed slightly wrong and awkward to adjust once in, and the flex cable end at the extruder requires better stress relief IMO. I added ~6cm of heatshrink tubing around it which works great
  • The provided slicer is horrible, I only tried it out to see if it’d fix my z blobbing problems. Fortunately Prusa Slicer works great with these printers

I tuned mine up with the usual tools until I was satisfied with the prints using the stock firmware. Then I installed klipper and set up pressure advance and input shaping, vastly improving performance and usability.

20mm calibration cubes printed 1) on the stock firmware, 2) Klipper with a speed profile, and 3) Klipper with a detail profile (i.e. slower outer perimeters):

Here’s my current Prusa Slicer config files for the printer itself (Klipper) and my 0.16mm layer height optimal speed print profile.

Here’s what my Klipper START_PRINT and END_PRINT macros ended up looking like:

[gcode_macro START_PRINT]
  {% set TOTAL_LAYER_COUNT = params.TOTAL_LAYER_COUNT|int %}
  {% set BED_TEMP = params.BED_TEMP|float %}
  {% set EXTRUDER_TEMP = params.EXTRUDER_TEMP|float %}

  G90 ; use absolute coordinates
  M83 ; extruder relative mode
  M140 S{BED_TEMP} ; set final bed temp
  M104 S{EXTRUDER_TEMP - 90} ; set temporary nozzle temp to prevent oozing during homing and auto bed leveling
  G4 S10 ; allow partial nozzle warmup
  G28 ; home all axis
  M190 S{BED_TEMP} ; wait for bed temp to stabilize so that the bed mesh is accurate
  M104 S{EXTRUDER_TEMP} ; set final nozzle temp
  G1 Z50 F240
  G1 X2 Y10 F3000
  M109 S{EXTRUDER_TEMP} ; wait for nozzle temp to stabilize
  G1 Z0.28 F240
  G92 E0
  G1 Y140 E10 F1500 ; prime the nozzle
  G1 X2.3 F5000
  G92 E0
  G1 Y10 E10 F1200 ; prime the nozzle
  G92 E0

[gcode_macro END_PRINT]
  M140 S0 ; turn off heatbed
  M104 S0 ; turn off temperature
  M107 ; turn off fan
  # Move nozzle away from print while retracting
  G1 X-2 Y-2 E-3 F300
  # Raise nozzle by 10mm
  G1 Z10 F3000
  # Move out of the way
  G0 X20 Y150
  # Disable steppers
  M84 X Y E