In previous post, I mentioned my experience with provisioning data structures via CSOM. I also wrote that I’ll have a look at SPMeta2.

Test model

I’ll create very basic data structure. List of logical operations:

  • create site column SPMeta2_field,
  • create content type SPMeta2 content type,
  • create list SPMeta2 list,
  • add SPMeta2_field to SPMeta2 content type,
  • add SPMeta2 content type to SPMeta2 list.

I’m executing 5 simple operations, so I’m expecting around 5 calls to SharePoint.

I’ll just point out, that data structure so simple puts me in a disadvantage when we’re discussing performance. More about that in next parts.


Let’s see the code. It’s possible that parts of this are not required. It’s based on a sample from SPMeta2 website, so I assume that’s the most optimal way.

using SPMeta2.CSOM.Services;
using SPMeta2.Definitions;
using SPMeta2.Definitions.Fields;
using SPMeta2.Enumerations;
using SPMeta2.Syntax.Default;

Can somebody explain number of required using statements here? I’d have to add just one namespace to deploy it using CSOM, why does a wrapper needs five?

private static void SPMeta2Test(ClientContext context)
    var field = new TextFieldDefinition
        Title = "SPMeta2_field",
        InternalName = "SPMeta2_field",
        Group = "SPMeta2",
        Id = new Guid("97b41579-a73d-41b5-910d-b8ecd84b9b21"),
        FieldType = BuiltInFieldTypes.Note,

    var contentType = new ContentTypeDefinition
        Name = "SPMeta2 content type",
        Id = new Guid("996c3a43-5b94-470c-b742-548e830450e0"),
        ParentContentTypeId = BuiltInContentTypeId.Item,
        Group = "SPMeta2",

    var list = new ListDefinition
        Title = "SPMeta2 list",
        TemplateType = BuiltInListTemplateTypeId.GenericList,
        CustomUrl = "SPMeta2"

    var siteModel = SPMeta2Model.NewSiteModel(site =>
        site.AddContentType(contentType, ct =>
            ct.AddContentTypeFieldLink(new ContentTypeFieldLinkDefinition
                FieldId = field.Id

    var webModel = SPMeta2Model.NewWebModel(web =>
        web.AddList(list, l =>
            l.AddContentTypeLink(new ContentTypeLinkDefinition
                ContentTypeName = contentType.Name

    var csomProvisionService = new CSOMProvisionService();
    csomProvisionService.DeploySiteModel(context, siteModel);
    csomProvisionService.DeployWebModel(context, webModel);

It’s not as hassle-free as they advertise, but this post was supposed to be about performance, so I’ll leave it.


Quote from the website:

SPMeta2: a rock-solid API to provision them all

Spent two hours trying to deploy single field to O365. Failed. I don’t have access to on prem env from home. I’ll try at the office tomorrow.


Tested exactly the same code at the office and it worked. Can’t really tell if it’s SPMeta2 fault or maybe recent update to O365.

Either way, not so rock-solid.

How many calls does it take…

I created very simple model, with 5 artifacts to provision (field, content type, field link, list and content type link).

Poorly optimized code requires 8 CSOM calls:

  1. Load existing field.
  2. Create field or update if exists.
  3. Load existing content type.
  4. Create content type or update existing.
  5. Add field link.
  6. Load existing list.
  7. Create list or update existing.
  8. Add content type link.

Seems reasonable, right? So how much better is SPMeta2?

It requires 26 calls. Wait, what?

Twenty. Six. Calls.

Yup. Fiddler doesn’t lie. Analysis of what happens there is subject of the next part.