**Disclaimer: I don't use eshell, so take this with a grain of salt.**

`eshell` appears to call `eshell-write-history` to write history, which takes an optional argument `append` which defaults to `nil`. This argument seems to be unused in `eshell` presently, but does appear to work (it passes the argument through to `write-region`, which does properly append).

There are a couple of options here.

1. `(setq eshell-save-history-on-exit nil)` and call `eshell-write-history` yourself
2. Redefine `eshell-write-history` to satisfy your requirement.

Personally, I'd go with 1.

As an example:

    (setq eshell-save-history-on-exit nil)
    (defun eshell-append-history ()
      "Call `eshell-write-history' with the `append' parameter set to `t'."
      (when eshell-history-ring
        (let ((newest-cmd-ring (make-ring 1)))
          (ring-insert newest-cmd-ring (car (ring-elements eshell-history-ring)))
          (let ((eshell-history-ring newest-cmd-ring))
            (eshell-write-history eshell-history-file-name t)))))
    (add-hook eshell-pre-command-hook #'eshell-append-history)

*Thanks to @joseph-garvin for the corrected, working `eshell-append-history` function*

This doesn't handle dynamically loading the new history contents into a shell (eg run command `X` in shell A, and having it appear in history in shell B without reloading; like zsh's SHARE_HISTORY). I don't know how efficient `eshell-read-history` is, so I'd be hesitant to run it in a hook.

It is also possible that you will end up with duplicate entries with this `eshell-append-history` function. You may need to do some shenanigans with clearing all but the most recent entry from `eshell-history-ring`, then resetting it to the old value after writing history.

E.g.

    (let ((old-ring (copy-list eshell-history-ring)))
      (setq eshell-history-ring (list (car eshell-history-ring)))
      ; write
      (setq eshell-history-ring old-ring))