Shrinking a database

Jul 4, 2011 at 8:44 AM

The documentation suggest that the only way to reduce the size taken by the DB is to use the esentutl command:

To shrink a file, use the defragmentation feature of the esentutl.exe utility program.

I am just trying to verify if there is a way to do this in code, while the DB is in operation

Alternatively, is there a way to get notify when the DB is growing? I want to implement a quota feature, and I would like to cancel operations when the DB is about to grow over the quota.

Jul 5, 2011 at 10:36 PM

The bad news:

  • You cannot shrink the database online (an often requested feature).
  • You can't get a grow notification.

What can you do:

  • Set a hard quota on the database with JetAttachDatabase2
  • Periodically get the size of the database with JetGetDatabaseInfo. The code would look like this:

int databaseSpaceOwned;
Api.JetGetDatabaseInfo(session, dbid, out databaseSpaceOwned, JET_DbInfo.SpaceOwned);

I suggest the second method because it is more flexible.


Jan 6, 2012 at 3:21 PM


You cannot shrink the database online (an often requested feature).</blockquote>


So when and how do you suggest to automate this process ?


(I want to use ManagedEsent on device that must require zero manual maintenance).

Jan 20, 2012 at 8:40 PM

You would need to dismount the database cleanly, and then defrag it with:

esentutl.exe -d foo.edb -o

The -o option suppresses any pop-up dialogs (which may happen when running Integrity Check [esentutl.exe -g] on a database that wasn't shut down cleanly). Defragmenting a database this way actually creates an entirely new file, copies everything over sequentially, and deletes the original. In the worst case you'll need about 110% free space (for a 100 MB database, you'll need 110 MB free). The extra 10% is used by bookkeeping during this process.

If it is dirty, you may need to replay the logs first:

esentut.exe -r edb (Or programmatically do a JetInit, and then a Term).

I hope that helps.



Jan 21, 2012 at 1:13 AM

Hello Martin,

Thanks for the information.

What is the exit code of the esentutl.exe on success and failure?
I am running this in code and wish to check the exit code.

Also, in my case I create the database once and only use it (read only) after that.
When is the best time to delete the log files; before or after the defragmentation?
The log files are huge and I do not really need them after the database or the
persistent dictionary is created. Any other tip to keep it compact after creation is
very welcome (currently over 800 MB). 

Best regards,

Jan 21, 2012 at 1:24 AM

It's zero for success. The error codes it uses are the JET_err's, e.g.:
#define JET_errLogDiskFull     -529  /* Log disk full */
(It was easier to paste the C value than the C# value :)

Log file usage shouldn't be a problem if you have circular logging enabled; they'll be cleaned up automatically.

If you don't have circular logging enabled, then you can delete them safely ONLY when the database is cleanly shut down. Once they're deleted, then the logs will start over at generation 0.

You can use space hints when you create your tables, which control how quickly each individual table grows. This is an advanced feature. :) I can't remember if it's in the current ManagedEsent drop or not, and I've got to go now (sorry!). The C version is at .


Jan 21, 2012 at 3:31 AM

Hello Martin,

Thanks for the support and the information.

Best regards,