Book a demo
  1. Home
  2. Articles
  3. Data & platform

WITSML & real-time data · worked example

WITSML explained: objects, servers and real-time feeds

DrillIQ drilling engineeringUpdated 1 October 202612 min read

A live drilling screen is only as good as the chain behind it: sensors, an acquisition system, a WITSML server, a satellite link and the application that reads it. WITSML is the standard that lets those systems agree on what a reading is, which well it belongs to and when it was taken. This article explains the objects and the servers, works out how late a live reading really is and how much data a day of logging makes, and lists the checks that catch a feed going wrong.

What WITSML is

WITSML, the Wellsite Information Transfer Standard Markup Language, is a data standard published by Energistics. It defines two things: a data model for wells and everything recorded about them, written as XML schemas, and an interface through which applications read and write that data. Version 1.4.1.1 remains in wide use on rigs and in operations centres. Version 2.0 changed both the model and the transport; the two are compared in WITSML 1.4.1 against 2.0 and ETP.

Three roles meet in any WITSML set-up. Producers measure: the mud-logging unit, the drilling data recorder, the MWD and LWD surface systems. Servers, also called stores, hold the data as WITSML objects. Consumers read it: real-time monitoring, engineering models, reporting. A provider's server may sit at the rig or in its data centre, and a consumer may be anywhere with a route to it.

WITSML did not replace everything before it. At the rig, many systems still exchange WITS Level 0, a plain-text stream of numbered records and items, typically sent once a second over a serial line or a network socket. Record 1, item 14 is average hookload, for example. WITS0 carries values with little context: no well identity, and units only by prior agreement between the two ends. WITSML adds identity, units and history.

The object model

Every WITSML 1.4.1.1 object sits in a hierarchy: a well, its wellbores, and the objects recorded against each wellbore. Each object carries its own identifier, the uid, and its parents' identifiers, uidWell and uidWellbore. An identifier only has to be unique within its parent. These are the objects a drilling team meets most often:

Common WITSML 1.4.1.1 objects
ObjectWhat it holdsGrows while drilling
wellName, location, time zone, field and countryNo
wellboreOne hole: the main bore, a pilot hole or a sidetrack, and its parentNo
logChannels indexed by time or depth: a header naming each curve and its unit, then rows of valuesYes
trajectorySurvey stations: measured depth, inclination, azimuth, TVD, dogleg severityYes
mudLogLithology by interval, gas readings, showsYes
rig, bhaRun, tubularThe rig's equipment and the string in the holeNo
fluidsReport, opsReport, messageMud checks, daily operations reports, time-stamped eventsNew ones are added

The log does most of the work. Its header lists each curve in a logCurveInfo element with its mnemonic, unit and data type. Its data block names the mnemonics and units once, then sends each row as one line of comma-separated text, index first. A time log is indexed by date and time, a depth log by measured depth, and the same sensor can appear in both, sampled differently.

Log, trajectory and mudLog are growing objects. While the well is drilled, rows, stations and intervals are added to the same object, and its objectGrowing flag is true. Reading growing objects well is most of what "real-time WITSML" means.

Store and streaming

WITSML 1.x is a store. A server offers a small set of SOAP web-service calls: WMLS_GetFromStore to read; WMLS_AddToStore, WMLS_UpdateInStore and WMLS_DeleteFromStore to write; WMLS_GetCap and WMLS_GetVersion to find out what the server supports. Reads are queries by template. The reader sends an XML skeleton of the object with empty elements where it wants values, plus options such as returnElements=header-only or data-only to say how much comes back.

Nothing arrives unless someone asks. Streaming works the other way round: the producer pushes each new value as it is measured. WITS0 does this at the rig, and so does ETP, the WebSocket protocol that carries WITSML 2.0. With a 1.4.1.1 store, live data means asking for new rows often.

Following a growing log

An application following a log keeps a cursor: the last index it has stored. Each poll asks for rows from that index on, with startDateTimeIndex for a time log or startIndex and its unit for a depth log. The server answers from the cursor inclusive, so the reader drops the repeated boundary row and moves its cursor to the newest row it stored. Servers cap how much one answer carries. When the cap is hit, the answer comes back with Result 2, "partial", and the reader asks again from the last row it got. DrillIQ's own store caps an answer at 10,000 rows, so reading a day of a one-second log takes nine requests.

Two things trip up simple followers. New logs and new curves appear part-way through a well, so the headers have to be re-read now and then. And rows can change behind the cursor: a gap filled later from a file, or a corrected value. A follower that only looks forward never sees them. WITSML 1.4.1.1 has a standard object for this, the changeLog, which records the index range of each change so a reader can fetch that range again. Not every server keeps one.

How late a live reading is

Each step in the chain waits for the next. Take a rig on a geostationary satellite link, with the provider's WITSML server at the rig and the reading application in the office. The assumptions below are illustrative; replace them with your rig's settings.

  1. Sampling. The acquisition system records every second, so a change waits on average half a second to be sampled, and at most one.
  2. The server's write. Here the acquisition system appends rows to its WITSML log every 5 s: 2.5 s of waiting on average, 5 s at worst.
  3. The link. A geostationary satellite is 35,786 km up, and a request and its answer cross that distance four times: 4 × 35,786 km ÷ 299,792 km/s = 0.48 s at least, before any ground equipment. Call it 0.6 s.
  4. The reader. DrillIQ's follower pauses 2 s after each pass, and a pass takes about one round trip, so it reads every 2.6 s: 1.3 s of waiting on average and 2.6 s at worst. Pushing the row to the browser adds about 0.1 s.
  5. Total. 0.5 + 2.5 + 0.6 + 1.4 = 5.0 s on average, and 1.0 + 5.0 + 0.6 + 2.7 = 9.3 s at worst.
Figure 1 From measurement to screen: a latency budget
  • Sampling every 1 s
  • Rig server writes rows
  • Satellite round trip
  • DrillIQ reads, then pushes
  • Freshness limit
024681012Average · Sampling every 1 s: 0.5 sAverage · Rig server writes rows: 2.5 sAverage · Satellite round trip: 0.6 sAverage · DrillIQ reads, then pushes: 1.4 s5.0AverageWorst case · Sampling every 1 s: 1.0 sWorst case · Rig server writes rows: 5.0 sWorst case · Satellite round trip: 0.6 sWorst case · DrillIQ reads, then pushes: 2.7 s9.3Worst caseWorst, 1 s writes · Sampling every 1 s: 1.0 sWorst, 1 s writes · Rig server writes rows: 1.0 sWorst, 1 s writes · Satellite round trip: 0.6 sWorst, 1 s writes · DrillIQ reads, then pushes: 2.7 s5.3Worst, 1 s writesRig Watch: fresh up to 8 sSeconds from measurement to screen

Hand calculation with illustrative assumptions: 1 s sampling, the rig's WITSML server appending rows every 5 s, a 0.6 s geostationary round trip, DrillIQ's follower pausing 2 s between passes and 0.1 s to the browser. Average waits are half of each interval.

Show the data
Sampling every 1 sRig server writes rowsSatellite round tripDrillIQ reads, then pushes
Average0.52.50.61.4
Worst case1.05.00.62.7
Worst, 1 s writes1.01.00.62.7

The largest item is the server's write interval, then the reader's poll interval, and the satellite comes third. Both intervals are settings, and each costs on average half its length. If the server wrote every second, the worst case would fall to 5.3 s with no change to the link.

That matters for how a screen marks freshness. DrillIQ's Rig Watch calls a reading fresh up to 8 s after the time it was measured, stale up to 30 s, and dead after that. With 5 s server writes the worst case of 9.3 s is past 8 s, so a healthy feed would flick to stale now and then. When that happens, ask the provider for the write interval before blaming the link.

How much data a day of logging makes

Data volume is rows a day times bytes a row. In a 1.4.1.1 log each row is text: a 24-character time stamp, the <data> tags and a line break (14 bytes), and about 8 bytes for each value with its comma. Forty channels make 24 + 14 + 40 × 8 = 358 bytes a row. At one row a second that is 86,400 rows, or 30.9 MB a day.

Figure 2 WITSML log data per day, by sample rate and channel count
  • 80 channels
  • 40 channels
  • 20 channels
0100200300400500600012345678910Samples per second, each channelLog data per day (MB)One sample a second: 30.9 MB for 40 channels80 channels: 586 MB40 channels: 309 MB20 channels: 171 MB

Hand calculation: rows a day × bytes a row. A row is a 24-byte time stamp, 14 bytes of tags and line break, and about 8 bytes per value with its comma, as text in a WITSML 1.4.1.1 log. Envelopes and headers are left out.

Show the data
Rate80 channels40 channels20 channels
0.00.00.00.0
0.211.76.23.4
0.529.315.58.6
1.058.630.917.1
2.0117.261.934.2
5.0292.9154.785.5
10.0585.8309.3171.1

Volume grows in a straight line with channels and with sample rate: 309 MB a day for 40 channels at ten samples a second, 586 MB for 80. A 256 kbit/s link moves about 2.8 GB a day, so even the largest of these fits. On most feeds the limits are the number of requests and the waits between them, which is why the interval settings above matter more than bandwidth.

Channel mapping and units

The same quantity arrives under different names. One system sends HKLA, the WITS short name for average hookload; another sends "Hookload" or "Hook Load"; a third uses its own code. Units vary as much: hookload in klbf, kdaN, tf or "klbs"; pressure in psi, kPa or bar; mud density in ppg, SG or kg/m³. Before a model can use the data, each source channel has to be mapped to one meaning and one unit. A sound mapping follows a few rules:

  • Store the unit on each mapping row. Two rigs can send one mnemonic in different units, and average and maximum torque from one rig can differ by a factor of 1,000 when one is in kft·lbf and the other in ft·lbf.
  • A unit has to fit the channel's kind of quantity. A percentage mapped to a flow rate is an error, and no conversion fixes it.
  • Prefer the averaged channel. WITS separates hookload (HKLD) from average hookload (HKLA), and engineering models are written for the averages.
  • Map one source curve to each channel in a log. If measured, vertical and returns depth are all mapped to hole depth, their rows interleave and the trace jumps between them.
  • Keep time stamps in UTC. A rig clock in local time, read as UTC, shifts every row by the time-zone offset and makes the data look hours late or early.

Data-quality checks

A feed can be connected and still be wrong. These checks are worth automating:

Checks on a live feed
CheckWhat it looks forWhat it usually means
GapsMissing rows in the index; null markers such as −999.25A cut link, an acquisition restart, a sensor out of service
LatencyEach sample's time stamp against its arrival timeThe write or poll interval, the link, a wrong time zone
SilenceNo new rows for minutes from a source that should be liveA stopped service or a dead connection
RangeValues outside physical limits, such as hookload above the rig's ratingA unit error or a failing sensor
SpikesA one-sample jump on one channel that related channels don't showElectrical noise or a transmission error
Flat linesThe same value for many samples while the rig is workingA frozen sensor or a system repeating its last value
DuplicatesThe same rows served twice, or shifted by a whole number of hoursA time-zone or replay fault at the source

Spikes and flat lines need judgement. A hookload spike as the string is picked up off bottom is real; the same spike with no movement of the block is not. Gaps need a plan before they happen. If the rig buffers data through an outage and sends it later, or a provider supplies a file to fill the hole, the receiving system has to accept rows behind its cursor without duplicating them. Writes keyed on the index make that safe, because a row sent twice is stored once.

A checklist for the rig team

  • Ask the provider which WITSML version and objects the server offers, and how often it writes new rows.
  • Check that the rig's clocks are synchronised and that time stamps go out in UTC.
  • Map every channel with its unit, and have an engineer approve the mapping before the data feeds any model.
  • Keep to one source curve per channel in each log.
  • Set the freshness limit above the chain's worst-case latency, so a healthy feed doesn't flicker.
  • Watch for silence, gaps, out-of-range values and flat lines, and show on screen how each was judged.
  • Agree how gaps will be filled after an outage, and confirm the receiving system re-reads them.

How DrillIQ handles it

DrillIQ's WITSML module connects to WITSML 1.3.1.1 and 1.4.1.1 servers over SOAP, receives WITS0 over TCP and UDP, and imports LAS and CSV files. It files a server's object tree in Project Explorer without fetching any rows (logs, trajectories, mud logs, rigs, messages, tubulars, wellbore geometries, BHA runs, risks, fluids reports and formation markers) and ingests only the logs and channels you select. Auto-map suggests a standard channel and unit conversion for each source curve, and approval is refused while a unit doesn't fit its channel. A follower polls each log for new rows with a 2 s pause between passes, re-reads any range a server's changeLog reports every 30 s, and refreshes growing trajectories every 90 s. The Health view shows each source's state and how it was judged, the Log Viewer plots the data against time and depth, and Rig Watch marks each reading fresh, stale or dead by its own time stamp.

At the rig, the Rig Connect agent reads WITS0, Modbus, OPC UA, a rig-site WITSML server or dropped files, buffers them on disk through link outages, and writes them with signed requests to DrillIQ's own WITSML 1.4.1.1 store, where each rig's well is set up and followed automatically, leaving only the channel mapping for an engineer to approve. The live views only read: nothing is sent back to the rig. Where each part can run is covered in on-premises deployment and drilling data sovereignty.

Book a demo See all capabilities

References

  1. Energistics. WITSML Data Schema, version 1.4.1.1.
  2. Energistics. WITSML Store Application Program Interface (API), version 1.4.1.
  3. Energistics. Energistics Transfer Protocol (ETP) Specification, version 1.2.
  4. W3C. Simple Object Access Protocol (SOAP) 1.1. W3C Note, 8 May 2000.